Relocate xcsv format functions. (#297)
authortsteven4 <tsteven4@users.noreply.github.com>
Thu, 14 Feb 2019 13:35:27 +0000 (06:35 -0700)
committerGitHub <noreply@github.com>
Thu, 14 Feb 2019 13:35:27 +0000 (06:35 -0700)
Many funtions for the xcsv format were in csv_util.cc
instead of xcsv.cc.  This commit moves the xcsv format
specific functions to xcsv.cc, and leaves the possibly
shared utility functions in csv_util.cc.

xcsv.h is added to communicate shared xcsv style handling
with vecs.cc.

CMakeLists.txt
GPSBabel.pro
Makefile.in
csv_util.cc
csv_util.h
defs.h
src/core/file.h
vecs.cc
xcsv.cc
xcsv.h [new file with mode: 0644]

index 6345c59188498a464c74415f26992a1896a33f60..613a28d2d96b9d6e4ccdab6c691c9f2c8f59a0b3 100644 (file)
@@ -149,6 +149,7 @@ set(HEADERS
   session.h
   shapelib/shapefil.h
   strptime.h
+  xcsv.h
   xmlgeneric.h
   zlib/crc32.h
   zlib/deflate.h
index ffa94894f81c94359c57f5d96b1a906484af6a77..8adf38825a1b5e1a7ec640108c5cd849b568d8c3 100644 (file)
@@ -133,6 +133,7 @@ HEADERS =  \
        session.h \
        shapelib/shapefil.h \
        strptime.h \
+  xcsv.h \
        xmlgeneric.h \
        zlib/crc32.h \
        zlib/deflate.h \
index 9255946dceb51cd4b79c1bb9d18c91b0f429f243..a40268856c6861f52580c919a97f7abd84c4bebc 100644 (file)
@@ -434,703 +434,745 @@ toolinfo:
        -$(QMAKE) -v
 
 # Machine generated from here down.
-alan.o: alan.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h
-an1.o: an1.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  an1sym.h
+alan.o: alan.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+an1.o: an1.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h an1sym.h
 arcdist.o: arcdist.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h arcdist.h filter.h filterdefs.h grtcirc.h
-bcr.o: bcr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  csv_util.h garmin_tables.h
-bend.o: bend.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  bend.h filter.h filterdefs.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h arcdist.h filter.h filterdefs.h grtcirc.h
+bcr.o: bcr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h csv_util.h garmin_tables.h
+bend.o: bend.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h bend.h filter.h filterdefs.h grtcirc.h
 brauniger_iq.o: brauniger_iq.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h gbser.h
 bushnell.o: bushnell.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 bushnell_trl.o: bushnell_trl.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
-cet.o: cet.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h
+cet.o: cet.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 cet_util.o: cet_util.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h src/core/logging.h cet/ansi_x3_4_1968.h \
 cet/cp1252.h cet/iso_8859_8.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h src/core/logging.h cet/ansi_x3_4_1968.h \
+ cet/cp1252.h cet/iso_8859_8.h
 compegps.o: compegps.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h csv_util.h jeeps/gpsmath.h \
-  jeeps/gpsport.h
-cst.o: cst.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h
-csv_util.o: csv_util.cc csv_util.h queue.h defs.h config.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  grtcirc.h src/core/logging.h strptime.h xcsv_tokens.gperf
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h jeeps/gpsmath.h \
+ jeeps/gpsport.h
+cst.o: cst.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h
+csv_util.o: csv_util.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h csv_util.h
 delgpl.o: delgpl.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 destinator.o: destinator.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
 jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
 jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
 jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  strptime.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h cet_util.h garmin_fs.h \
jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h strptime.h
 dg-100.o: dg-100.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbser.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h
 discard.o: discard.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h discard.h filter.h filterdefs.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h discard.h filter.h filterdefs.h
 dmtlog.o: dmtlog.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h xmlgeneric.h
 duplicate.o: duplicate.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h duplicate.h filter.h filterdefs.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h duplicate.h filter.h \
+ filterdefs.h
 easygps.o: easygps.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 energympro.o: energympro.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 enigma.o: enigma.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
-exif.o: exif.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+exif.o: exif.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h
 explorist_ini.o: explorist_ini.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h explorist_ini.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h explorist_ini.h
 f90g_track.o: f90g_track.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 fatal.o: fatal.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 filter_vecs.o: filter_vecs.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h arcdist.h filter.h bend.h discard.h duplicate.h \
-  filterdefs.h height.h interpolate.h nukedata.h polygon.h position.h \
-  radius.h reverse_route.h smplrout.h sort.h stackfilter.h swapdata.h \
-  trackfilter.h transform.h validate.h gbversion.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h arcdist.h filter.h bend.h \
+ discard.h duplicate.h filterdefs.h height.h interpolate.h nukedata.h \
+ polygon.h position.h radius.h reverse_route.h smplrout.h sort.h \
+ stackfilter.h swapdata.h trackfilter.h transform.h validate.h \
+ gbversion.h
 formspec.o: formspec.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 g7towin.o: g7towin.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h garmin_tables.h strptime.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
+ jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h jeeps/gpsmath.h \
+ strptime.h
 garmin.o: garmin.cc cet_util.h config.h cet.h defs.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h garmin_device_xml.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsserial.h
+ zlib/zconf.h config.h gbfile.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h garmin_device_xml.h garmin_fs.h jeeps/gps.h \
+ jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h grtcirc.h \
+ jeeps/gpsserial.h
 garmin_device_xml.o: garmin_device_xml.cc defs.h config.h queue.h \
-  zlib/zlib.h zlib/zconf.h gbfile.h cet.h inifile.h session.h \
-  src/core/datetime.h src/core/optional.h garmin_device_xml.h \
-  xmlgeneric.h
+ zlib/zlib.h zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h garmin_device_xml.h xmlgeneric.h
 garmin_fit.o: garmin_fit.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 garmin_fs.o: garmin_fs.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
 jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
 jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
 jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  garmin_tables.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h cet_util.h garmin_fs.h \
jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h
 garmin_gpi.o: garmin_gpi.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  garmin_gpi.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h cet_util.h garmin_fs.h \
+ jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
+ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
+ jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h garmin_gpi.h \
+ jeeps/gpsmath.h
 garmin_tables.o: garmin_tables.cc garmin_tables.h defs.h config.h queue.h \
 zlib/zlib.h zlib/zconf.h gbfile.h cet.h inifile.h session.h \
 src/core/datetime.h src/core/optional.h jeeps/gpsmath.h \
 jeeps/gpsport.h src/core/logging.h
zlib/zlib.h zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h \
+ src/core/logging.h
 garmin_txt.o: garmin_txt.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h garmin_tables.h grtcirc.h strptime.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h cet_util.h csv_util.h \
+ garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
+ jeeps/gpsdevice.h jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h \
+ jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+ jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
+ garmin_tables.h grtcirc.h jeeps/gpsmath.h strptime.h
 garmin_xt.o: garmin_xt.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 gbfile.o: gbfile.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h src/core/logging.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h src/core/logging.h
 gbser.o: gbser.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbser.h gbser_private.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h gbser_private.h
 gbser_posix.o: gbser_posix.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h gbser_private.h
-gdb.o: gdb.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 cet_util.h csv_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
 jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
 jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
 jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
 garmin_tables.h grtcirc.h
-geo.o: geo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 src/core/file.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h gbser.h gbser_private.h
+gdb.o: gdb.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \
jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsmath.h
+geo.o: geo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h src/core/file.h defs.h
 geojson.o: geojson.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h src/core/file.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h src/core/file.h defs.h
 ggv_bin.o: ggv_bin.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 ggv_log.o: ggv_log.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h jeeps/gpsmath.h jeeps/gpsport.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h jeeps/gpsmath.h jeeps/gpsport.h
 ggv_ovl.o: ggv_ovl.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h
 globals.o: globals.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbversion.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbversion.h
 globalsat_sport.o: globalsat_sport.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h gbser.h
 glogbook.o: glogbook.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h src/core/file.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h src/core/file.h defs.h xmlgeneric.h
 gnav_trl.o: gnav_trl.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 googledir.o: googledir.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h xmlgeneric.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h xmlgeneric.h
 gopal.o: gopal.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h csv_util.h grtcirc.h jeeps/gpsmath.h \
 jeeps/gpsport.h strptime.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h grtcirc.h jeeps/gpsmath.h \
+ jeeps/gpsport.h strptime.h
 gpssim.o: gpssim.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 gpsutil.o: gpsutil.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h magellan.h
-gpx.o: gpx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
 jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
 jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
 jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h \
 src/core/file.h src/core/logging.h src/core/xmlstreamwriter.h \
-  src/core/xmltag.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h magellan.h
+gpx.o: gpx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h jeeps/gpssend.h \
jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
jeeps/gpsrqst.h garmin_tables.h src/core/file.h defs.h \
src/core/logging.h src/core/xmlstreamwriter.h src/core/xmltag.h
 grtcirc.o: grtcirc.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h
-gtm.o: gtm.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h
+gtm.o: gtm.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
 gtrnctr.o: gtrnctr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
 height.o: height.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h height.h heightgrid.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h height.h heightgrid.h
 hiketech.o: hiketech.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h src/core/xmlstreamwriter.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h src/core/xmlstreamwriter.h xmlgeneric.h
 holux.o: holux.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h holux.h
-html.o: html.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h holux.h
+html.o: html.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
 humminbird.o: humminbird.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
-igc.o: igc.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
+igc.o: igc.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h
 ignrando.o: ignrando.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h xmlgeneric.h
-igo8.o: igo8.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h
-ik3d.o: ik3d.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
+igo8.o: igo8.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h
+ik3d.o: ik3d.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h xmlgeneric.h
 inifile.o: inifile.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h src/core/file.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h src/core/file.h defs.h
 internal_styles.o: internal_styles.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 interpolate.o: interpolate.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h filterdefs.h filter.h grtcirc.h interpolate.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h filterdefs.h filter.h grtcirc.h \
+ interpolate.h
 itracku.o: itracku.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h
-jeeps/gpsapp.o: jeeps/gpsapp.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h \
-  jeeps/gpsserial.h jeeps/gpsusbint.h
-jeeps/gpscom.o: jeeps/gpscom.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h
+jeeps/gpsapp.o: jeeps/gpsapp.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsserial.h \
+ jeeps/gpsusbint.h
+jeeps/gpscom.o: jeeps/gpscom.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h
 jeeps/gpsdevice.o: jeeps/gpsdevice.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/gpsserial.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
 jeeps/gpsdevice_ser.o: jeeps/gpsdevice_ser.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/gpsserial.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
 jeeps/gpsdevice_usb.o: jeeps/gpsdevice_usb.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/garminusb.h jeeps/gpsusbcommon.h jeeps/gpsusbint.h
-jeeps/gpslibusb.o: jeeps/gpslibusb.cc config.h mac/libusb/usb.h \
-  jeeps/gps.h jeeps/../defs.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  defs.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsusbcommon.h \
-  jeeps/../garmin_device_xml.h
-jeeps/gpsmath.o: jeeps/gpsmath.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsdatum.h
-jeeps/gpsmem.o: jeeps/gpsmem.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
-jeeps/gpsprot.o: jeeps/gpsprot.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
-jeeps/gpsread.o: jeeps/gpsread.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
-jeeps/gpsrqst.o: jeeps/gpsrqst.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
-jeeps/gpssend.o: jeeps/gpssend.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsusbcommon.h \
+ jeeps/gpsusbint.h
+jeeps/gpslibusb.o: jeeps/gpslibusb.cc config.h jeeps/gps.h \
+ jeeps/../defs.h jeeps/../config.h jeeps/../queue.h zlib/zlib.h \
+ zlib/zconf.h jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h \
+ jeeps/../inifile.h jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsusbcommon.h \
+ jeeps/../garmin_device_xml.h
+jeeps/gpsmath.o: jeeps/gpsmath.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsdatum.h
+jeeps/gpsmem.o: jeeps/gpsmem.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h
+jeeps/gpsprot.o: jeeps/gpsprot.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h
+jeeps/gpsread.o: jeeps/gpsread.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
+jeeps/gpsrqst.o: jeeps/gpsrqst.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h
+jeeps/gpssend.o: jeeps/gpssend.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsserial.h
 jeeps/gpsserial.o: jeeps/gpsserial.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/../gbser.h jeeps/gpsserial.h gbser_posix.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/../gbser.h jeeps/gpsserial.h \
+ gbser_posix.h
 jeeps/gpsusbcommon.o: jeeps/gpsusbcommon.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/garminusb.h jeeps/gpsusbcommon.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsusbcommon.h
 jeeps/gpsusbread.o: jeeps/gpsusbread.cc jeeps/garminusb.h \
-  jeeps/gpsdevice.h jeeps/gps.h jeeps/../defs.h config.h queue.h \
-  zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h session.h \
-  src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
-  jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
-  jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsusbint.h
+ jeeps/gpsdevice.h jeeps/gps.h jeeps/../defs.h jeeps/../config.h \
+ jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h jeeps/../gbfile.h \
+ jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h jeeps/../session.h \
+ jeeps/../src/core/datetime.h jeeps/../src/core/optional.h \
+ jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
+ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
+ jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsusbint.h
 jeeps/gpsusbsend.o: jeeps/gpsusbsend.cc jeeps/gps.h jeeps/../defs.h \
-  config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  jeeps/garminusb.h jeeps/gpsusbint.h
-jeeps/jgpsutil.o: jeeps/jgpsutil.cc jeeps/gps.h jeeps/../defs.h config.h \
-  queue.h zlib/zlib.h zlib/zconf.h gbfile.h defs.h cet.h inifile.h \
-  session.h src/core/datetime.h src/core/optional.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/garminusb.h jeeps/gpsusbint.h
+jeeps/jgpsutil.o: jeeps/jgpsutil.cc jeeps/gps.h jeeps/../defs.h \
+ jeeps/../config.h jeeps/../queue.h zlib/zlib.h zlib/zconf.h config.h \
+ jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../inifile.h \
+ jeeps/../session.h jeeps/../src/core/datetime.h \
+ jeeps/../src/core/optional.h jeeps/gpsport.h jeeps/gpsdevice.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h
 jogmap.o: jogmap.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h \
 xmlgeneric.h
-jtr.o: jtr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  csv_util.h
-kml.o: kml.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 grtcirc.h src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
-  xmlgeneric.h
-lmx.o: lmx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h \
+ xmlgeneric.h
+jtr.o: jtr.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h csv_util.h
+kml.o: kml.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h grtcirc.h src/core/file.h defs.h \
src/core/xmlstreamwriter.h src/core/xmltag.h xmlgeneric.h
+lmx.o: lmx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h xmlgeneric.h
 lowranceusr.o: lowranceusr.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
-mac/libusb/darwin.o: mac/libusb/darwin.c config.h mac/libusb/usbi.h \
-  mac/libusb/usb.h mac/libusb/error.h
-mac/libusb/descriptors.o: mac/libusb/descriptors.c mac/libusb/usbi.h \
-  mac/libusb/usb.h mac/libusb/error.h
-mac/libusb/error.o: mac/libusb/error.c mac/libusb/usb.h \
-  mac/libusb/error.h
-mac/libusb/usb.o: mac/libusb/usb.c mac/libusb/usbi.h mac/libusb/usb.h \
-  mac/libusb/error.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h
 maggeo.o: maggeo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h csv_util.h magellan.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h csv_util.h magellan.h xmlgeneric.h
 magproto.o: magproto.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h explorist_ini.h gbser.h magellan.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h explorist_ini.h gbser.h magellan.h
 main.o: main.cc cet.h cet_util.h config.h defs.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h csv_util.h filterdefs.h filter.h src/core/file.h \
-  src/core/usasciicodec.h
zlib/zconf.h config.h gbfile.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h csv_util.h filterdefs.h filter.h src/core/file.h \
defs.h src/core/usasciicodec.h
 mapasia.o: mapasia.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 mapbar_track.o: mapbar_track.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 mapfactor.o: mapfactor.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h src/core/file.h src/core/xmlstreamwriter.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h src/core/file.h defs.h \
+ src/core/xmlstreamwriter.h
 mapsend.o: mapsend.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h magellan.h mapsend.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h magellan.h mapsend.h
 mapsource.o: mapsource.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h garmin_tables.h jeeps/gpsmath.h \
+ jeeps/gpsport.h
 mkshort.o: mkshort.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h
-mmo.o: mmo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h
+mmo.o: mmo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 mtk_locus.o: mtk_locus.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h gbser.h
 mtk_logger.o: mtk_logger.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h gbser.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h gbser.h
 mynav.o: mynav.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 navicache.o: navicache.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h src/core/file.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h cet_util.h src/core/file.h \
+ defs.h
 naviguide.o: naviguide.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h csv_util.h jeeps/gpsmath.h jeeps/gpsport.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h csv_util.h jeeps/gpsmath.h \
+ jeeps/gpsport.h
 navilink.o: navilink.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbser.h jeeps/gpsmath.h jeeps/gpsport.h navilink.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h jeeps/gpsmath.h jeeps/gpsport.h navilink.h
 navitel.o: navitel.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
 netstumbler.o: netstumbler.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h csv_util.h
-nmea.o: nmea.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 cet_util.h gbser.h jeeps/gpsmath.h jeeps/gpsport.h src/core/logging.h \
-  strptime.h
-nmn4.o: nmn4.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h csv_util.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h cet_util.h csv_util.h
+nmea.o: nmea.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h gbser.h jeeps/gpsmath.h jeeps/gpsport.h \
src/core/logging.h strptime.h
+nmn4.o: nmn4.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h csv_util.h
 nukedata.o: nukedata.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h filterdefs.h filter.h nukedata.h
-osm.o: osm.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  xmlgeneric.h
-ozi.o: ozi.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h csv_util.h jeeps/gpsmath.h jeeps/gpsport.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h nukedata.h
+osm.o: osm.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
+ozi.o: ozi.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h jeeps/gpsmath.h \
+ jeeps/gpsport.h
 parse.o: parse.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
-pcx.o: pcx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  cet_util.h csv_util.h garmin_tables.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
+pcx.o: pcx.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h cet_util.h csv_util.h garmin_tables.h
 pocketfms_bc.o: pocketfms_bc.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 pocketfms_fp.o: pocketfms_fp.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h xmlgeneric.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h xmlgeneric.h
 pocketfms_wp.o: pocketfms_wp.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h csv_util.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h csv_util.h
 polygon.o: polygon.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h polygon.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h polygon.h
 position.o: position.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h grtcirc.h position.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h grtcirc.h position.h
 psitrex.o: psitrex.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h garmin_tables.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h garmin_tables.h
 queue.o: queue.cc queue.h
 radius.o: radius.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h grtcirc.h radius.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h grtcirc.h radius.h
 random.o: random.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
-  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
-  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
-  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
+ jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h jeeps/gpssend.h \
+ jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
+ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
+ jeeps/gpsrqst.h jeeps/gpsmath.h
 raymarine.o: raymarine.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h csv_util.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h csv_util.h
 reverse_route.o: reverse_route.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h filterdefs.h filter.h reverse_route.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h filterdefs.h filter.h \
+ reverse_route.h
 rgbcolors.o: rgbcolors.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h
 route.o: route.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h
 saroute.o: saroute.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h
-sbn.o: sbn.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  navilink.h
-sbp.o: sbp.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  navilink.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h
+sbn.o: sbn.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h navilink.h
+sbp.o: sbp.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h navilink.h
 session.o: session.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 shape.o: shape.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h shapelib/shapefil.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h shapelib/shapefil.h
 shapelib/dbfopen.o: shapelib/dbfopen.c shapelib/shapefil.h
 shapelib/safileio.o: shapelib/safileio.c shapelib/shapefil.h
 shapelib/shpopen.o: shapelib/shpopen.c shapelib/shapefil.h
 skyforce.o: skyforce.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 skytraq.o: skytraq.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbser.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h
 smplrout.o: smplrout.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h grtcirc.h smplrout.h
-sort.o: sort.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  filterdefs.h filter.h sort.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h grtcirc.h smplrout.h
+sort.o: sort.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h filterdefs.h filter.h sort.h
 src/core/usasciicodec.o: src/core/usasciicodec.cc src/core/usasciicodec.h
 src/core/xmlstreamwriter.o: src/core/xmlstreamwriter.cc \
 src/core/xmlstreamwriter.h
+ src/core/xmlstreamwriter.h
 src/core/ziparchive.o: src/core/ziparchive.cc src/core/ziparchive.h \
 defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h cet.h \
-  inifile.h session.h src/core/datetime.h src/core/optional.h \
 zlib/contrib/minizip/zip.h zlib/contrib/minizip/ioapi.h \
 src/core/logging.h
defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h gbfile.h \
defs.h cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
+ zlib/contrib/minizip/zip.h zlib/contrib/minizip/ioapi.h \
+ src/core/logging.h
 stackfilter.o: stackfilter.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h filterdefs.h filter.h stackfilter.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h filterdefs.h filter.h \
+ stackfilter.h
 stmsdf.o: stmsdf.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h csv_util.h jeeps/gpsmath.h \
 jeeps/gpsport.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h jeeps/gpsmath.h \
jeeps/gpsport.h grtcirc.h src/core/logging.h
 stmwpp.o: stmwpp.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h csv_util.h cet_util.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h csv_util.h cet_util.h
 strptime.o: strptime.c config.h strptime.h
 subrip.o: subrip.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 swapdata.o: swapdata.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h swapdata.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h swapdata.h
 tef_xml.o: tef_xml.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
 teletype.o: teletype.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
-text.o: text.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+text.o: text.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
 tiger.o: tiger.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h csv_util.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h
 tmpro.o: tmpro.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h csv_util.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h
 tomtom.o: tomtom.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
-tpg.o: tpg.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h
-tpo.o: tpo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+tpg.o: tpg.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
+tpo.o: tpo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
 trackfilter.o: trackfilter.cc defs.h config.h queue.h zlib/zlib.h \
 zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h grtcirc.h strptime.h \
-  trackfilter.h xmlgeneric.h
zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
src/core/datetime.h src/core/optional.h filterdefs.h filter.h grtcirc.h \
strptime.h trackfilter.h xmlgeneric.h
 transform.o: transform.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h filterdefs.h filter.h transform.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h filterdefs.h filter.h \
+ transform.h
 unicsv.o: unicsv.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h garmin_tables.h src/core/logging.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h csv_util.h garmin_fs.h jeeps/gps.h \
+ jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \
+ jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+ jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+ jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h jeeps/gpsmath.h \
+ src/core/logging.h
 units.o: units.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
-util.o: util.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+util.o: util.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h src/core/xmltag.h
 util_crc.o: util_crc.cc
-v900.o: v900.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h
+v900.o: v900.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 validate.o: validate.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h filterdefs.h filter.h validate.h
-vcf.o: vcf.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
-  jeeps/gpsmath.h jeeps/gpsport.h
-vecs.o: vecs.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 csv_util.h gbversion.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h filterdefs.h filter.h validate.h
+vcf.o: vcf.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
+vecs.o: vecs.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h csv_util.h gbversion.h xcsv.h src/core/file.h defs.h
 vidaone.o: vidaone.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 vitosmt.o: vitosmt.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h grtcirc.h
 vitovtt.o: vitovtt.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
-vpl.o: vpl.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
-  cet.h inifile.h session.h src/core/datetime.h src/core/optional.h
+ config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
+vpl.o: vpl.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h
 waypt.o: waypt.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
 jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
 jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
 jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
-  grtcirc.h src/core/logging.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h jeeps/gpssend.h \
jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
jeeps/gpsrqst.h grtcirc.h src/core/logging.h
 wbt-200.o: wbt-200.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h gbser.h grtcirc.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h gbser.h grtcirc.h
 wfff_xml.o: wfff_xml.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
 wintec_tes.o: wintec_tes.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h
-xcsv.o: xcsv.cc csv_util.h queue.h defs.h config.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h src/core/file.h \
-  src/core/logging.h
-xhtmlent.o: xhtmlent.cc
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h
+xcsv.o: xcsv.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
+ gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h csv_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
+ jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h jeeps/gpssend.h \
+ jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
+ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
+ jeeps/gpsrqst.h grtcirc.h jeeps/gpsmath.h jeeps/gpsport.h \
+ src/core/file.h defs.h src/core/logging.h strptime.h xcsv.h \
+ xcsv_tokens.gperf
 xmlgeneric.o: xmlgeneric.cc defs.h config.h queue.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
-  src/core/optional.h cet_util.h src/core/file.h xmlgeneric.h
+ zlib/zconf.h config.h gbfile.h cet.h inifile.h session.h \
+ src/core/datetime.h src/core/optional.h cet_util.h src/core/file.h \
+ defs.h xmlgeneric.h
 xmltag.o: xmltag.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h cet_util.h src/core/xmltag.h
-xol.o: xol.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h gbfile.h \
 cet.h inifile.h session.h src/core/datetime.h src/core/optional.h \
 garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h src/core/file.h \
-  src/core/xmlstreamwriter.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h cet_util.h src/core/xmltag.h
+xol.o: xol.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h config.h \
gbfile.h cet.h inifile.h session.h src/core/datetime.h \
src/core/optional.h garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h \
src/core/file.h defs.h src/core/xmlstreamwriter.h xmlgeneric.h
 yahoo.o: yahoo.cc defs.h config.h queue.h zlib/zlib.h zlib/zconf.h \
-  gbfile.h cet.h inifile.h session.h src/core/datetime.h \
 src/core/optional.h xmlgeneric.h
config.h gbfile.h cet.h inifile.h session.h src/core/datetime.h \
+ src/core/optional.h xmlgeneric.h
 zlib/adler32.o: zlib/adler32.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \
 config.h
+ config.h
 zlib/compress.o: zlib/compress.c zlib/zlib.h zlib/zconf.h config.h
 zlib/contrib/minizip/ioapi.o: zlib/contrib/minizip/ioapi.c \
 zlib/contrib/minizip/ioapi.h zlib/zlib.h zlib/zconf.h config.h
+ zlib/contrib/minizip/ioapi.h zlib/zlib.h zlib/zconf.h config.h
 zlib/contrib/minizip/zip.o: zlib/contrib/minizip/zip.c zlib/zlib.h \
 zlib/zconf.h config.h zlib/contrib/minizip/zip.h \
 zlib/contrib/minizip/ioapi.h zlib/contrib/minizip/crypt.h
+ zlib/zconf.h config.h zlib/contrib/minizip/zip.h \
+ zlib/contrib/minizip/ioapi.h zlib/contrib/minizip/crypt.h
 zlib/crc32.o: zlib/crc32.c zlib/zutil.h zlib/zlib.h zlib/zconf.h config.h \
 zlib/crc32.h
+ zlib/crc32.h
 zlib/deflate.o: zlib/deflate.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \
 zlib/zconf.h config.h
+ zlib/zconf.h config.h
 zlib/gzclose.o: zlib/gzclose.c zlib/gzguts.h zlib/zlib.h zlib/zconf.h \
 config.h
+ config.h
 zlib/gzlib.o: zlib/gzlib.c zlib/gzguts.h zlib/zlib.h zlib/zconf.h \
 config.h
+ config.h
 zlib/gzread.o: zlib/gzread.c zlib/gzguts.h zlib/zlib.h zlib/zconf.h \
 config.h
+ config.h
 zlib/gzwrite.o: zlib/gzwrite.c zlib/gzguts.h zlib/zlib.h zlib/zconf.h \
 config.h
+ config.h
 zlib/infback.o: zlib/infback.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \
 config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h
+ config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h
 zlib/inffast.o: zlib/inffast.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \
 config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h
+ config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h
 zlib/inflate.o: zlib/inflate.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \
 config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h
+ config.h zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h
 zlib/inftrees.o: zlib/inftrees.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \
 config.h zlib/inftrees.h
+ config.h zlib/inftrees.h
 zlib/trees.o: zlib/trees.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \
 zlib/zconf.h config.h zlib/trees.h
+ zlib/zconf.h config.h zlib/trees.h
 zlib/uncompr.o: zlib/uncompr.c zlib/zlib.h zlib/zconf.h config.h
 zlib/zutil.o: zlib/zutil.c zlib/zutil.h zlib/zlib.h zlib/zconf.h config.h \
 zlib/gzguts.h
+ zlib/gzguts.h
 internal_styles.cc: mkstyle.sh $(srcdir)/style/*.style
        $(srcdir)/mkstyle.sh > internal_styles.cc || (rm -f internal_styles.cc ; exit 1)
index 202dffe368eb660d53175628194c84058c69b68f..ee73344e81e6fe8dab9b44da527097ebe36d0e5f 100644 (file)
 
  */
 
-#include <QtCore/QChar>            // for QChar
-#include <QtCore/QDateTime>        // for QDateTime, QDate
-#include <QtCore/QString>          // for QString, QCharRef
-#include <QtCore/QTextStream>      // for QTextStream
-#include <QtCore/QtGlobal>         // for qAsConst
+#include <cmath>           // for fabs
+#include <cstdio>          // for size_t
+#include <cstdlib>         // for atof, strtod
+#include <cctype>          // for isspace
+#include <cstring>         // for strlen, strchr, strncmp, strcmp, memmove, strcpy, strcspn, strncpy
 
-#include "csv_util.h"
-#include "defs.h"
-#include "garmin_fs.h"
-#include "grtcirc.h"
-#include "jeeps/gpsmath.h"
-#include "src/core/logging.h"
-#include "src/core/optional.h"
-#include "strptime.h"
+#include <QtCore/QRegExp>  // for QRegExp
+#include <QtCore/QString>  // for QString
 
-#include <cmath>
-#include <cstdio>
-#include <cstdlib>
+#include "defs.h"
+#include "csv_util.h"
 
 #define MYNAME "CSV_UTIL"
 
-/* macros */
-#define LAT_DIR(a) a < 0.0 ? 'S' : 'N'
-#define LON_DIR(a) a < 0.0 ? 'W' : 'E'
-#define NONULL(a) a.isNull() ? "" : CSTRc(a)
 #define ISWHITESPACE(a) ((a == ' ') || (a == '\t'))
 
-/* convert excel time (days since 1900) to time_t and back again */
-#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0)
-#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0)
-
-#define GPS_DATUM_WGS84                118
-
-
-/*
- * Internal numeric value to associate with each keyword in a style file.
- * To add new keywords, just add an entry here, handle it in the switch
- * statements below, add it to xcsv_tokens.in, and rebuild on a system
- * that has GNU gperf on it.
- */
-typedef enum {
-  XT_unused = 0,
-  XT_ALT_FEET,
-  XT_ALT_METERS,
-  XT_ANYNAME,
-  XT_CADENCE,
-  XT_CITY,
-  XT_CONSTANT,
-  XT_COUNTRY,
-  XT_DESCRIPTION,
-  XT_EXCEL_TIME,
-  XT_FACILITY,
-  XT_FILENAME,
-  XT_FORMAT,
-  XT_GEOCACHE_CONTAINER,
-  XT_GEOCACHE_DIFF,
-  XT_GEOCACHE_HINT,
-  XT_GEOCACHE_LAST_FOUND,
-  XT_GEOCACHE_PLACER,
-  XT_GEOCACHE_TERR,
-  XT_GEOCACHE_TYPE,
-  XT_GEOCACHE_ISAVAILABLE,
-  XT_GEOCACHE_ISARCHIVED,
-  XT_GMT_TIME,
-  XT_GPS_FIX,
-  XT_GPS_HDOP,
-  XT_GPS_PDOP,
-  XT_GPS_SAT,
-  XT_GPS_VDOP,
-  XT_HEART_RATE,
-  XT_HMSG_TIME,
-  XT_HMSL_TIME,
-  XT_ICON_DESCR,
-  XT_IGNORE,
-  XT_INDEX,
-  XT_ISO_TIME,
-  XT_ISO_TIME_MS,
-  XT_LATLON_HUMAN_READABLE,
-  XT_LAT_DECIMAL,
-  XT_LAT_DECIMALDIR,
-  XT_LAT_DIR,
-  XT_LAT_DIRDECIMAL,
-  XT_LAT_HUMAN_READABLE,
-  XT_LAT_INT32DEG,
-  XT_LAT_DDMMDIR,
-  XT_LAT_NMEA,
-  XT_LOCAL_TIME,
-  XT_LON_DECIMAL,
-  XT_LON_DECIMALDIR,
-  XT_LON_DIR,
-  XT_LON_DIRDECIMAL,
-  XT_LON_HUMAN_READABLE,
-  XT_LON_INT32DEG,
-  XT_LON_DDMMDIR,
-  XT_LON_NMEA,
-  XT_MAP_EN_BNG,
-  XT_NOTES,
-  XT_NET_TIME,
-  XT_PATH_COURSE,
-  XT_PATH_DISTANCE_KM,
-  XT_PATH_DISTANCE_METERS,
-  XT_PATH_DISTANCE_MILES,
-  XT_PATH_SPEED,
-  XT_PATH_SPEED_KNOTS,
-  XT_PATH_SPEED_KPH,
-  XT_PATH_SPEED_MPH,
-  XT_PHONE_NR,
-  XT_POSTAL_CODE,
-  XT_POWER,
-  XT_ROUTE_NAME,
-  XT_SHORTNAME,
-  XT_STATE,
-  XT_STREET_ADDR,
-  XT_TEMPERATURE,
-  XT_TEMPERATURE_F,
-  XT_TIMET_TIME,
-  XT_TIMET_TIME_MS,
-  XT_TRACK_NAME,
-  XT_TRACK_NEW,
-  XT_URL,
-  XT_UTM,
-  XT_UTM_ZONE,
-  XT_UTM_ZONEC,
-  XT_UTM_ZONEF,
-  XT_UTM_EASTING,
-  XT_UTM_NORTHING,
-  XT_URL_LINK_TEXT,
-  XT_YYYYMMDD_TIME
-} xcsv_token;
-
-#include "xcsv_tokens.gperf"
-
-#if CSVFMTS_ENABLED
-/****************************************************************************/
-/* obligatory global struct                                                 */
-/****************************************************************************/
-
-extern char* xcsv_urlbase;
-extern char* prefer_shortnames;
-
-XcsvFile xcsv_file;
-static double pathdist = 0;
-static double oldlon = 999;
-static double oldlat = 999;
-
-static int waypt_out_count;
-static route_head* csv_track, *csv_route;
-
-struct xcsv_parse_data {
-  QString rte_name;
-  QString trk_name;
-  bool new_track{false};
-  double utm_northing{0};
-  double utm_easting{0};
-  double utm_zone{0};
-  char utm_zonec{'N'};
-  UrlLink* link_{nullptr};
-  gpsbabel_optional::optional<bool> lat_dir_positive;
-  gpsbabel_optional::optional<bool> lon_dir_positive;
-};
-#endif // CSVFMTS_ENABLED
-
 
 /*********************************************************************/
 /* csv_stringclean() - remove any unwanted characters from string.   */
@@ -381,12 +235,11 @@ csv_lineparse(const char* stringstart, const char* delimited_by,
   return (tmp);
 }
 
-#if CSVFMTS_ENABLED
 /*****************************************************************************/
 /* dec_to_intdeg() - convert decimal degrees to integer degreees             */
 /*    usage: i = dec_to_intdeg(31.1234);                                     */
 /*****************************************************************************/
-static int
+int
 dec_to_intdeg(const double d)
 {
   int ideg = 0;
@@ -404,7 +257,7 @@ dec_to_intdeg(const double d)
 /* intdeg_to_dec() - convert integer degrees to decimal degreees             */
 /*    usage: lat = dec_to_intdeg(ilat);                                      */
 /*****************************************************************************/
-static double
+double
 intdeg_to_dec(const int ideg)
 {
   double d;
@@ -423,7 +276,7 @@ intdeg_to_dec(const int ideg)
 /* usage: lat = decdir_to_dec("W90.1234");                                   */
 /*        lat = decdir_to_dec("30.1234N");                                  */
 /*****************************************************************************/
-static double
+double
 decdir_to_dec(const char* decdir)
 {
   char* p;
@@ -455,7 +308,7 @@ decdir_to_dec(const char* decdir)
 /* usage: lat = ddmmdir_to_degrees("W90.1234");                              */
 /*        lat = ddmmdir_to_degrees("30.1234N");                              */
 /*****************************************************************************/
-static double
+double
 ddmmdir_to_degrees(const char* ddmmdir)
 {
   // if not N or E, prepend a '-' to ddmm2degrees input
@@ -466,7 +319,6 @@ ddmmdir_to_degrees(const char* ddmmdir)
   return ddmm2degrees(atof(ddmmdir));
 
 }
-#endif
 
 /*****************************************************************************
  * human_to_dec() - convert a "human-readable" lat and/or lon to decimal
@@ -639,7 +491,6 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which)
   }
 }
 
-#if CSVFMTS_ENABLED
 /*
  * dec_to_human - convert decimal degrees to human readable
  */
@@ -715,1511 +566,3 @@ dec_to_human(const char* format, const char* dirs, double val)
   xfree(subformat);
   return buff;
 }
-
-/*****************************************************************************/
-/* xcsv_file_init() - prepare xcsv_file for first use.                       */
-/*****************************************************************************/
-void xcsv_file_init()
-{
-  xcsv_file.is_internal = false;
-  xcsv_file.field_delimiter = QString();
-  xcsv_file.field_encloser = QString();
-  xcsv_file.record_delimiter = QString();
-  xcsv_file.badchars = QString();
-  xcsv_file.file = nullptr;
-  xcsv_file.stream = nullptr;
-  xcsv_file.codec = nullptr;
-  xcsv_file.fname = QString();
-  xcsv_file.description = nullptr;
-  xcsv_file.extension = nullptr;
-
-  xcsv_file.prologue.clear();
-  xcsv_file.epilogue.clear();
-
-  xcsv_file.ifields.clear();
-  xcsv_file.ofields.clear();
-  /*
-   * Provide a sane default for CSV _files_.
-   */
-  xcsv_file.type = ff_type_file;
-
-  xcsv_file.mkshort_handle = mkshort_new_handle();
-  xcsv_file.gps_datum = GPS_DATUM_WGS84;
-}
-
-XcsvFile::XcsvFile() {
-  is_internal = false;
-  extension  = nullptr;
-//   xcsv_file_init();
-}
-
-static void validate_fieldmap(const field_map& fmp, bool is_output) {
-  if (fmp.key.isEmpty()) {
-    Fatal() << MYNAME << ": xcsv style is missing" <<
-            (is_output ? "output" : "input") << "field type.";
-  }
-  if (fmp.val.isNull()) {
-    Fatal() << MYNAME << ": xcsv style" << fmp.key.constData() << "is missing default.";
-  }
-  if (is_output && fmp.printfc.isNull()) {
-    Fatal() << MYNAME << ": xcsv style" << fmp.key.constData() << "output is missing format specifier.";
-  }
-}
-
-/*****************************************************************************/
-/* xcsv_ifield_add() - add input field to ifield queue.                      */
-/* usage: xcsv_ifield_add("DESCRIPTION", "", "%s")                           */
-/*****************************************************************************/
-void
-xcsv_ifield_add(const QString& qkey, const QString& qval, const QString& qpfc)
-{
-  QByteArray key = qkey.toUtf8();
-  QByteArray val = qval.toUtf8();
-  QByteArray pfc = qpfc.toUtf8();
-
-  struct xt_mapping* xm = Perfect_Hash::in_word_set(key.constData(), strlen(key.constData()));
-
-  field_map fmp(key, val, pfc, xm ? xm->xt_token : -1);
-  validate_fieldmap(fmp, false);
-
-  xcsv_file.ifields.append(fmp);
-}
-
-/*****************************************************************************/
-/* xcsv_ofield_add() - add output field to ofield queue.                     */
-/* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf")                      */
-/*****************************************************************************/
-void
-xcsv_ofield_add(const QString& qkey, const QString& qval, const QString& qpfc, unsigned options)
-{
-  QByteArray key = qkey.toUtf8();
-  QByteArray val = qval.toUtf8();
-  QByteArray pfc = qpfc.toUtf8();
-
-  struct xt_mapping* xm = Perfect_Hash::in_word_set(key.constData(), strlen(key.constData()));
-
-  field_map fmp(key, val, pfc, xm ? xm->xt_token : -1, options);
-  validate_fieldmap(fmp, true);
-
-  xcsv_file.ofields.append(fmp);
-}
-
-/*****************************************************************************/
-/* xcsv_prologue_add() - add prologue line to prologue queue                 */
-/* usage: xcsv_prologue_add("Four score and seven years ago today,")         */
-/*****************************************************************************/
-void
-xcsv_prologue_add(const QString& prologue)
-{
-  xcsv_file.prologue.append(prologue);
-}
-
-/*****************************************************************************/
-/* xcsv_epilogue_add() - add epilogue line to epilogue queue                 */
-/* usage: xcsv_epilogue_add("shall not perish from the earth.")              */
-/*****************************************************************************/
-void
-xcsv_epilogue_add(const QString& epilogue)
-{
-  xcsv_file.epilogue.append(epilogue);
-}
-
-static
-QDateTime
-yyyymmdd_to_time(const char* s)
-{
-  QDate d = QDate::fromString(s, "yyyyMMdd");
-  return QDateTime(d);
-}
-
-
-/*
- * sscanftime - Parse a date buffer using strftime format
- */
-static
-time_t
-sscanftime(const char* s, const char* format, const int gmt)
-{
-  struct tm stm;
-  memset(&stm, 0, sizeof(stm));
-
-  if (strptime(s, format, &stm)) {
-    if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) {
-      stm.tm_mday = 1;
-      stm.tm_mon = 0;
-      stm.tm_year = 70;
-    }
-    stm.tm_isdst = -1;
-    if (gmt) {
-      return mkgmtime(&stm);
-    } else {
-      return mktime(&stm);
-    }
-  }
-  // Don't fuss for empty strings.
-  if (*s) {
-    warning("date parse of string '%s' with format '%s' failed.\n",
-            s, format);
-  }
-  return 0;
-}
-
-static
-time_t
-addhms(const char* s, const char* format)
-{
-  time_t tt = 0;
-  int hour = 0;
-  int min = 0;
-  int sec = 0;
-
-  char* ampm = (char*) xmalloc(strlen(s) + 1);
-  int ac = sscanf(s, format, &hour, &min, &sec, ampm);
-  /* If no time format in arg string, assume AM */
-  if (ac < 4) {
-    ampm[0] = 0;
-  }
-  if (ac) {
-    tt = ((tolower(ampm[0])=='p') ? 43200 : 0) + 3600 * hour + 60 * min + sec;
-  }
-  xfree(ampm);
-
-  return tt;
-}
-
-static
-QString
-writetime(const char* format, time_t t, bool gmt)
-{
-  static struct tm* stmp;
-
-  if (gmt) {
-    stmp = gmtime(&t);
-  } else {
-    stmp = localtime(&t);
-  }
-
-  // It's unfortunate that we publish the definition of "strftime specifiers"
-  // in the style definitions.  For this reason, we have to bust everything
-  // down to a time_t and then let strftime handle them.
-
-  char tbuff[1024];
-  strftime(tbuff, sizeof tbuff, format, stmp);
-  return QString(tbuff);
-}
-
-static
-QString
-writetime(const char* format, const gpsbabel::DateTime& t, bool gmt)
-{
-  return writetime(format, t.toTime_t(), gmt);
-}
-
-QString
-writehms(const char* format, time_t t, int gmt)
-{
-  static struct tm no_time = tm();
-  static struct tm* stmp = &no_time;
-
-  if (gmt) {
-    stmp = gmtime(&t);
-  } else {
-    stmp = localtime(&t);
-  }
-
-  if (stmp == nullptr) {
-    stmp = &no_time;
-  }
-
-  return QString().sprintf(format,
-                            stmp->tm_hour, stmp->tm_min, stmp->tm_sec,
-                            (stmp->tm_hour >= 12 ? "PM" : "AM"));
-}
-
-QString
-writehms(const char* format, const gpsbabel::DateTime& t, int gmt)
-{
-  return writehms(format, t.toTime_t(), gmt);
-}
-
-static
-long
-time_to_yyyymmdd(const QDateTime& t)
-{
-  QDate d = t.date();
-  return d.year() * 10000 + d.month() * 100 + d.day();
-}
-
-static garmin_fs_t*
-gmsd_init(Waypoint* wpt)
-{
-  garmin_fs_t* gmsd = GMSD_FIND(wpt);
-  if (gmsd == nullptr) {
-    gmsd = garmin_fs_alloc(-1);
-    fs_chain_add(&wpt->fs, (format_specific_data*) gmsd);
-  }
-  return gmsd;
-}
-
-/*****************************************************************************/
-/* xcsv_parse_val() - parse incoming data into the waypt structure.          */
-/* usage: xcsv_parse_val("-123.34", *waypt, *field_map)                      */
-/*****************************************************************************/
-static void 
-xcsv_parse_val(const char* s, Waypoint* wpt, const field_map& fmp,
-               xcsv_parse_data* parse_data, const int line_no)
-{
-  const char* enclosure = "";
-  geocache_data* gc_data = nullptr;
-
-  if (fmp.printfc.isNull()) {
-    fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp.key.constData());
-  }
-
-  if (0 == strcmp(fmp.printfc.constData(), "\"%s\"")) {
-    enclosure = "\"";
-  }
-  switch (fmp.hashed_key) {
-  case XT_IGNORE:
-    /* IGNORE -- Categorically ignore this... */
-    break;
-  case XT_CONSTANT:
-    /* CONSTANT -- Ignore on Input... */
-    break;
-  case XT_ANYNAME:
-    /* ANYNAME -- Ignore -- this is output magic. */
-    break;
-  case XT_INDEX:
-    /* IGNORE -- Calculated Sequence # For Ouput*/
-    break;
-  case XT_SHORTNAME:
-    wpt->shortname = csv_stringtrim(s, enclosure);
-    break;
-  case XT_DESCRIPTION:
-    wpt->description = csv_stringtrim(s, enclosure);
-    break;
-  case XT_NOTES:
-    wpt->notes = csv_stringtrim(s, "");
-    break;
-  case XT_URL:
-    if (!parse_data->link_) {
-      parse_data->link_ = new UrlLink;
-    }
-    parse_data->link_->url_ = QString(s).trimmed();
-    break;
-  case XT_URL_LINK_TEXT:
-    if (!parse_data->link_) {
-      parse_data->link_ = new UrlLink;
-    }
-    parse_data->link_->url_link_text_ = QString(s).trimmed();
-    break;
-  case XT_ICON_DESCR:
-    wpt->icon_descr = QString(s).trimmed();
-    break;
-
-    /* LATITUDE CONVERSIONS**************************************************/
-  case XT_LAT_DECIMAL:
-    /* latitude as a pure decimal value */
-    wpt->latitude = atof(s);
-    break;
-  case XT_LAT_DECIMALDIR:
-  case XT_LAT_DIRDECIMAL:
-    /* latitude as a decimal with N/S in it. */
-    wpt->latitude = decdir_to_dec(s);
-    break;
-  case XT_LAT_INT32DEG:
-    /* latitude as a 32 bit integer offset */
-    wpt->latitude = intdeg_to_dec((int) atof(s));
-    break;
-  case XT_LAT_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 1);
-    break;
-  case XT_LAT_DDMMDIR:
-    wpt->latitude = ddmmdir_to_degrees(s);
-    break;
-  case XT_LAT_NMEA:
-    wpt->latitude = ddmm2degrees(atof(s));
-    break;
-    // XT_LAT_10E is handled outside the switch.
-    /* LONGITUDE CONVERSIONS ***********************************************/
-  case XT_LON_DECIMAL:
-    /* longitude as a pure decimal value */
-    wpt->longitude = atof(s);
-    break;
-  case XT_LON_DECIMALDIR:
-  case XT_LON_DIRDECIMAL:
-    /* longitude as a decimal with N/S in it. */
-    wpt->longitude = decdir_to_dec(s);
-    break;
-  case XT_LON_INT32DEG:
-    /* longitude as a 32 bit integer offset  */
-    wpt->longitude = intdeg_to_dec((int) atof(s));
-    break;
-  case XT_LON_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 2);
-    break;
-  case XT_LON_DDMMDIR:
-    wpt->longitude = ddmmdir_to_degrees(s);
-    break;
-  case XT_LON_NMEA:
-    wpt->longitude = ddmm2degrees(atof(s));
-    break;
-    // case XT_LON_10E is handled outside the switch.
-    /* LAT AND LON CONVERSIONS ********************************************/
-  case XT_LATLON_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 0);
-    break;
-    /* DIRECTIONS **********************************************************/
-  case XT_LAT_DIR:
-    /* latitude N/S. */
-    if (*s == 'n' || *s == 'N') {
-      parse_data->lat_dir_positive = true;
-    } else if (*s == 's' || *s == 'S') {
-      parse_data->lat_dir_positive = false;
-    } else {
-      warning("parse of string '%s' on line number %d as LAT_DIR failed.  Expected 'n', 'N', 's' or 'S'.\n", s, line_no);
-    }
-    break;
-  case XT_LON_DIR:
-    /* longitude E/W. */
-    if (*s == 'e' || *s == 'E') {
-      parse_data->lon_dir_positive = true; 
-    } else if (*s == 'w' || *s == 'W') {
-      parse_data->lon_dir_positive = false;
-    } else {
-      warning("parse of string '%s' on line number %d as LON_DIR failed.  Expected 'e', 'E', 'w' or 'W'.\n", s, line_no);
-    }
-    break;
-    /* SPECIAL COORDINATES/GRID */
-  case XT_MAP_EN_BNG:
-    parse_coordinates(s, DATUM_OSGB36, grid_bng,
-                      &wpt->latitude, &wpt->longitude, MYNAME);
-    break;
-  case XT_UTM_ZONE:
-    parse_data->utm_zone = atoi(s);
-    break;
-  case XT_UTM_ZONEC:
-    parse_data->utm_zonec = s[0];
-    break;
-  case XT_UTM_ZONEF:
-    parse_data->utm_zone = atoi(s);
-    parse_data->utm_zonec = s[strlen(s) - 1];
-    break;
-  case XT_UTM_EASTING:
-    parse_data->utm_easting = atof(s);
-    break;
-  case XT_UTM_NORTHING:
-    parse_data->utm_northing = atof(s);
-    break;
-  case XT_UTM: {
-    char* ss;
-    int i = 0;
-
-    parse_data->utm_zone = strtod(s, &ss);
-    parse_data->utm_zonec = ss[i];
-    ss++;
-    parse_data->utm_easting = strtod(ss, &ss);
-    while (*ss && !isdigit(*ss)) {
-      ss++;
-    }
-    parse_data->utm_northing = strtod(ss, nullptr);
-  }
-  break;
-  /* ALTITUDE CONVERSIONS ************************************************/
-  case XT_ALT_FEET: {
-    char *endptr;
-    double val = strtod(s, &endptr);
-    if ((val == 0 && s==endptr)) {
-      wpt->altitude = unknown_alt;
-    } else {
-      wpt->altitude = FEET_TO_METERS(val);
-      if (wpt->altitude < unknown_alt + 1) {
-        wpt->altitude = unknown_alt;
-      }
-    }
-  }
-  break;
-  case XT_ALT_METERS: {
-    char *endptr;
-    double val = strtod(s, &endptr);
-    if ((val == 0 && s==endptr)) {
-      wpt->altitude = unknown_alt;
-    } else {
-      wpt->altitude = val;
-      if (wpt->altitude < unknown_alt + 1) {
-        wpt->altitude = unknown_alt;
-      }
-    }
-  }
-  break;
-
-    /* PATH CONVERSIONS ************************************************/
-  case XT_PATH_SPEED:
-    WAYPT_SET(wpt, speed, atof(s));
-    break;
-  case XT_PATH_SPEED_KPH:
-    WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s)));
-    break;
-  case XT_PATH_SPEED_MPH:
-    WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s)));
-    break;
-  case XT_PATH_SPEED_KNOTS:
-    WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s)));
-    break;
-  case XT_PATH_COURSE:
-    WAYPT_SET(wpt, course, atof(s));
-    break;
-
-    /* TIME CONVERSIONS ***************************************************/
-  case XT_EXCEL_TIME:
-    /* Time as Excel Time  */
-    wpt->SetCreationTime(EXCEL_TO_TIMET(atof(s)));
-    break;
-  case XT_TIMET_TIME:
-    /* Time as time_t */
-    wpt->SetCreationTime((time_t) atol(s));
-    break;
-  case XT_TIMET_TIME_MS: {
-    /* Time as time_t in milliseconds */
-    int s_len = strlen(s);
-    if (s_len < 4) {
-      /* less than 1 epochsecond, an unusual case */
-      wpt->SetCreationTime(0, atoi(s));
-    } else {
-      char buff[32];
-      int off = s_len - 3;
-      strncpy(buff, s, off);
-      buff[off] = '\0';
-      time_t t = (time_t) atol(buff);
-      s += off;
-      strncpy(buff, s, 3);
-      buff[3] = '\0';
-      wpt->SetCreationTime(t, atoi(buff));
-    }
-  }
-  break;
-  case XT_YYYYMMDD_TIME:
-    wpt->SetCreationTime(yyyymmdd_to_time(s));
-    break;
-  case XT_GMT_TIME:
-    wpt->SetCreationTime(sscanftime(s, fmp.printfc.constData(), 1));
-    break;
-  case XT_LOCAL_TIME:
-    if (ugetenv("GPSBABEL_FREEZE_TIME").isNull()) {
-      wpt->creation_time += sscanftime(s, fmp.printfc.constData(), 0);
-    } else {
-      /* Force constant time zone for test */
-      wpt->creation_time += sscanftime(s, fmp.printfc.constData(), 1);
-    }
-    break;
-    /* Useful when time and date are in separate fields
-       GMT / Local offset is handled by the two cases above */
-  case XT_HMSG_TIME:
-  case XT_HMSL_TIME:
-    wpt->creation_time += addhms(s, fmp.printfc.constData());
-    break;
-  case XT_ISO_TIME:
-  case XT_ISO_TIME_MS:
-    wpt->SetCreationTime(xml_parse_time(s));
-    break;
-  case XT_NET_TIME: {
-    fatal("XT_NET_TIME can't have possibly ever worked.");
-//    time_t tt = wpt->GetCreationTime();
-//    dotnet_time_to_time_t(atof(s), &tt, &wpt->microseconds);
-  }
-  break;
-  case XT_GEOCACHE_LAST_FOUND:
-    wpt->AllocGCData()->last_found = yyyymmdd_to_time(s);
-    break;
-
-    /* GEOCACHING STUFF ***************************************************/
-  case XT_GEOCACHE_DIFF:
-    /* Geocache Difficulty as an int */
-    wpt->AllocGCData()->diff = atof(s) * 10;
-    break;
-  case XT_GEOCACHE_TERR:
-    /* Geocache Terrain as an int */
-    wpt->AllocGCData()->terr = atof(s) * 10;
-    break;
-  case XT_GEOCACHE_TYPE:
-    /* Geocache Type */
-    wpt->AllocGCData()->type = gs_mktype(s);
-    break;
-  case XT_GEOCACHE_CONTAINER:
-    wpt->AllocGCData()->container = gs_mkcont(s);
-    break;
-  case XT_GEOCACHE_HINT:
-    wpt->AllocGCData()->hint = QString(s).trimmed();
-    break;
-  case XT_GEOCACHE_PLACER:
-    wpt->AllocGCData()->placer = QString(s).trimmed();
-    break;
-  case XT_GEOCACHE_ISAVAILABLE:
-    gc_data = wpt->AllocGCData();
-    if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
-      gc_data->is_available = status_false;
-    } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
-      gc_data->is_available = status_true;
-    } else {
-      gc_data->is_available = status_unknown;
-    }
-    break;
-  case XT_GEOCACHE_ISARCHIVED:
-    gc_data = wpt->AllocGCData();
-    if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
-      gc_data->is_archived = status_false;
-    } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
-      gc_data->is_archived = status_true;
-    } else {
-      gc_data->is_archived = status_unknown;
-    }
-    break;
-
-    /* GPS STUFF *******************************************************/
-  case XT_GPS_HDOP:
-    wpt->hdop = atof(s);
-    break;
-  case XT_GPS_VDOP:
-    wpt->vdop = atof(s);
-    break;
-  case XT_GPS_PDOP:
-    wpt->pdop = atof(s);
-    break;
-  case XT_GPS_SAT:
-    wpt->sat = atoi(s);
-    break;
-  case XT_GPS_FIX:
-    wpt->fix = (fix_type)(atoi(s)-(fix_type)1);
-    if (wpt->fix < fix_2d) {
-      if (!case_ignore_strcmp(s, "none")) {
-        wpt->fix = fix_none;
-      } else if (!case_ignore_strcmp(s, "dgps")) {
-        wpt->fix = fix_dgps;
-      } else if (!case_ignore_strcmp(s, "pps")) {
-        wpt->fix = fix_pps;
-      } else {
-        wpt->fix = fix_unknown;
-      }
-    }
-    break;
-    /* Tracks and routes *********************************************/
-  case XT_ROUTE_NAME:
-    parse_data->rte_name = csv_stringtrim(s, enclosure);
-    break;
-  case XT_TRACK_NEW:
-    parse_data->new_track = atoi(s);
-    break;
-  case XT_TRACK_NAME:
-    parse_data->trk_name = csv_stringtrim(s, enclosure);
-    break;
-
-    /* OTHER STUFF ***************************************************/
-  case XT_PATH_DISTANCE_METERS:
-    wpt->odometer_distance = atof(s);
-    break;
-  case XT_PATH_DISTANCE_KM:
-    wpt->odometer_distance = atof(s) * 1000.0;
-    break;
-  case XT_PATH_DISTANCE_MILES:
-    wpt->odometer_distance = MILES_TO_METERS(atof(s));
-    break;
-  case XT_HEART_RATE:
-    wpt->heartrate = atoi(s);
-    break;
-  case XT_CADENCE:
-    wpt->cadence = atoi(s);
-    break;
-  case XT_POWER:
-    wpt->power = atof(s);
-    break;
-  case XT_TEMPERATURE:
-    wpt->temperature = atof(s);
-    break;
-  case XT_TEMPERATURE_F:
-    wpt->temperature = (FAHRENHEIT_TO_CELSIUS(atof(s)));
-    break;
-    /* GMSD ****************************************************************/
-  case XT_COUNTRY: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(country, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_STATE: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(state, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_CITY: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(city, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_STREET_ADDR: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(addr, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_POSTAL_CODE: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_PHONE_NR: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case XT_FACILITY: {
-    garmin_fs_t* gmsd = gmsd_init(wpt);
-    GMSD_SET(facility, csv_stringtrim(s, enclosure, 0));
-  }
-  break;
-  case -1:
-    if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
-      wpt->longitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
-    } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
-      wpt->latitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
-    } else {
-      warning(MYNAME ": Unknown style directive: %s\n", fmp.key.constData());
-    }
-    break;
-
-  default:
-    fatal("This can't happen\n");
-    break;
-  }
-}
-
-/*****************************************************************************/
-/* xcsv_data_read() - read input file, parsing lines, fields and handling    */
-/*                   any data conversion (the input meat)                    */
-/*****************************************************************************/
-void
-xcsv_data_read()
-{
-  int linecount = 0;
-  route_head* rte = nullptr;
-  route_head* trk = nullptr;
-
-  while (true) {
-    QString buff = xcsv_file.stream->readLine();
-    if (buff.isNull()) { 
-      break;
-    }
-    linecount++;
-    /* Whack trailing space; leading space may matter if our field sep
-     * is whitespace and we have leading whitespace.
-     */
-    // This could be hoisted out as a generic rtrim() if we need such a thing.
-    while(buff.size() > 0 && buff.at(buff.size() - 1).isSpace()) {
-      buff.chop(1); 
-    }
-
-    /* skip over x many lines on the top for the prologue... */
-    if ((linecount - 1) < xcsv_file.prologue.count()) {
-      continue;
-    }
-
-    /* We should skip over epilogue lines also.  Since we don't want to
-     * pre-read the file to know how many data lines we should be seeing,
-     * we take this cheap shot at the data and cross our fingers.
-     */
-    for(const auto& ogp : qAsConst(xcsv_file.epilogue)) {
-       if (ogp.startsWith(buff)) {
-         buff.clear();
-         break;
-       }
-    }
-    if (!buff.isEmpty()) {
-      Waypoint* wpt_tmp = new Waypoint;
-      // initialize parse data for accumulation of line results from all fields in this line.
-      xcsv_parse_data parse_data;
-      // tbuf is a temporary copy of buff since we modify it. :-(
-      char *tbuf = xstrdup(buff);
-      const char* s = tbuf;
-      s = csv_lineparse(s, CSTR(xcsv_file.field_delimiter),
-                        CSTR(xcsv_file.field_encloser), linecount);
-
-      if (xcsv_file.ifields.isEmpty()) {
-        fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", CSTR(xcsv_file.description)? CSTR(xcsv_file.description) : "unknown");
-      }
-
-      int ifield_idx = 0;
-
-      /* now rip the line apart, advancing the queue for each tear
-       * off the beginning of buff since there's no index into queue.
-       */
-      while (s) {
-        const field_map& fmp = xcsv_file.ifields.at(ifield_idx++);
-        xcsv_parse_val(s, wpt_tmp, fmp, &parse_data, linecount);
-
-        if (ifield_idx >= xcsv_file.ifields.size()) {
-          /* we've wrapped the queue. so stop parsing! */
-          while (s) {
-            s = csv_lineparse(nullptr, "\xff","",linecount);
-          }
-          break;
-        }
-
-        s = csv_lineparse(nullptr, CSTR(xcsv_file.field_delimiter),
-                          CSTR(xcsv_file.field_encloser), linecount);
-      }
-
-      // If XT_LAT_DIR(XT_LON_DIR) was an input field, and the latitude(longitude) is positive,
-      // assume the latitude(longitude) was the absolute value and take the sign from XT_LAT_DIR(XT_LON_DIR).
-      if (parse_data.lat_dir_positive.has_value() && !parse_data.lat_dir_positive.value() && (wpt_tmp->latitude > 0.0)) {
-        wpt_tmp->latitude = -wpt_tmp->latitude;
-      }
-      if (parse_data.lon_dir_positive.has_value() && !parse_data.lon_dir_positive.value() && (wpt_tmp->longitude > 0.0)) {
-        wpt_tmp->longitude = -wpt_tmp->longitude;
-      }
-
-      if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) {
-        double alt;
-        GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0,
-                                        &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum);
-      }
-
-      if (parse_data.utm_easting || parse_data.utm_northing) {
-        GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude,
-                                       &wpt_tmp->longitude,
-                                       parse_data.utm_easting, parse_data.utm_northing,
-                                       parse_data.utm_zone, parse_data.utm_zonec,
-                                       DATUM_WGS84);
-      }
-
-      if (parse_data.link_) {
-        wpt_tmp->AddUrlLink(*parse_data.link_);
-        delete parse_data.link_;
-        parse_data.link_ = nullptr;
-      }
-
-      switch (xcsv_file.datatype) {
-      case unknown_gpsdata:
-      case wptdata:
-        waypt_add(wpt_tmp);
-        break;
-      case trkdata:
-        if ((trk == nullptr) || parse_data.new_track) {
-          trk = route_head_alloc();
-          track_add_head(trk);
-        }
-        if (!parse_data.trk_name.isEmpty()) {
-          trk->rte_name = parse_data.trk_name;
-        }
-        track_add_wpt(trk, wpt_tmp);
-        break;
-      case rtedata:
-        if (rte == nullptr) {
-          rte = route_head_alloc();
-          route_add_head(rte);
-        }
-        if (!parse_data.rte_name.isEmpty()) {
-          rte->rte_name = parse_data.rte_name;
-        }
-        route_add_wpt(rte, wpt_tmp);
-        break;
-      default:
-        ;
-      }
-      xfree(tbuf);
-    }
-  }
-}
-
-static void
-xcsv_resetpathlen(const route_head* head)
-{
-  pathdist = 0;
-  oldlat = 999;
-  oldlon = 999;
-  csv_route = csv_track = nullptr;
-  switch (xcsv_file.datatype) {
-  case trkdata:
-    csv_track = const_cast<route_head*>(head);
-    break;
-  case rtedata:
-    csv_route = const_cast<route_head*>(head);
-    break;
-  default:
-    break;
-  }
-}
-
-/*****************************************************************************/
-/* xcsv_waypt_pr() - write output file, handling output conversions          */
-/*                  (the output meat)                                        */
-/*****************************************************************************/
-static void
-xcsv_waypt_pr(const Waypoint* wpt)
-{
-  QString buff;
-  double latitude, longitude;
-  int32 utmz;
-  double utme, utmn;
-  char utmzc;
-
-  buff[0] = '\0';
-
-  if (oldlon < 900) {
-    pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon),
-                                  RAD(wpt->latitude),RAD(wpt->longitude)));
-  }
-  longitude = oldlon = wpt->longitude;
-  latitude = oldlat = wpt->latitude;
-
-  QString write_delimiter;
-  if (xcsv_file.field_delimiter == "\\w") {
-    write_delimiter = " ";
-  } else {
-    write_delimiter = xcsv_file.field_delimiter;
-  }
-
-  QString description;
-  QString shortname;
-  if (wpt->shortname.isEmpty() || global_opts.synthesize_shortnames) {
-    if (!wpt->description.isEmpty()) {
-      if (global_opts.synthesize_shortnames) {
-        shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt);
-      } else {
-        shortname = csv_stringclean(wpt->description, xcsv_file.badchars);
-      }
-    } else {
-      /* no shortname available -- let shortname default on output */
-    }
-  } else {
-    shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars);
-  }
-  if (wpt->description.isEmpty()) {
-    if (!shortname.isEmpty()) {
-      description = csv_stringclean(shortname, xcsv_file.badchars);
-    } else {
-      /* no description -- let description default on output */
-    }
-  } else {
-    description = csv_stringclean(wpt->description, xcsv_file.badchars);
-  }
-
-  if (prefer_shortnames) {
-    description = shortname;
-  }
-
-  if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) {
-    double alt;
-    GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0,
-                                    &latitude, &longitude, &alt, xcsv_file.gps_datum);
-  }
-
-  int i = 0;
-  for (const auto& fmp : qAsConst(xcsv_file.ofields)) {
-    double lat = latitude;
-    double lon = longitude;
-    /*
-     * A klunky concept.   This should evaluate to true for any
-     * field if we think we don't have realistic value for it.
-     * This is used by the 'optional' attribute for suppressing
-     * fields on output.
-     */
-    int field_is_unknown = 0;
-
-    if ((i != 0) && !(fmp.options & OPTIONS_NODELIM)) {
-      *xcsv_file.stream << write_delimiter;
-    }
-
-    if (fmp.options & OPTIONS_ABSOLUTE) {
-      lat = fabs(lat);
-      lon = fabs(lon);
-    }
-
-    i++;
-
-    switch (fmp.hashed_key) {
-    case XT_IGNORE:
-      /* IGNORE -- Write the char printf conversion */
-      buff = QString().sprintf(fmp.printfc.constData(), "");
-      break;
-    case XT_INDEX:
-      buff = QString().sprintf(fmp.printfc.constData(), waypt_out_count + atoi(fmp.val.constData()));
-      break;
-    case XT_CONSTANT: {
-      auto cp = xcsv_get_char_from_constant_table(fmp.val.constData());
-      if (!cp.isEmpty()) {
-        buff = QString().sprintf(fmp.printfc.constData(), CSTR(cp));
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), fmp.val.constData());
-      }
-    }
-    break;
-    case XT_SHORTNAME:
-               buff = QString().sprintf(fmp.printfc.constData(),
-                shortname.isEmpty() ? fmp.val.constData() : CSTR(shortname));
-
-      break;
-    case XT_ANYNAME:
-      {
-      QString anyname = wpt->shortname;
-      if (anyname.isEmpty()) {
-        anyname = mkshort(xcsv_file.mkshort_handle, wpt->description);
-      }
-      if (anyname.isEmpty()) {
-        anyname = mkshort(xcsv_file.mkshort_handle, wpt->description);
-      }
-      if (anyname.isEmpty()) {
-        anyname = wpt->notes;
-      }
-      if (anyname.isEmpty()) {
-        anyname = fmp.val.constData();
-      }
-      buff = QString().sprintf(fmp.printfc.constData(), CSTR(anyname));
-      }
-
-      break;
-    case XT_DESCRIPTION:
-      buff = QString().sprintf(fmp.printfc.constData(),
-                description.isEmpty() ? fmp.val.constData() : CSTR(description));
-      break;
-    case XT_NOTES:
-      buff = QString().sprintf(fmp.printfc.constData(),
-                wpt->notes.isEmpty() ? fmp.val.constData() : CSTR(wpt->notes));
-      break;
-    case XT_URL: {
-      if (xcsv_urlbase) {
-        buff = xcsv_urlbase;
-      }
-      if (wpt->HasUrlLink()) {
-        UrlLink l = wpt->GetUrlLink();
-        buff += QString().sprintf(fmp.printfc.constData(), CSTR(l.url_));
-      } else {
-        buff += QString().sprintf(fmp.printfc.constData(), fmp.val.constData() && *fmp.val.constData() ? fmp.val.constData() : "\"\"");
-      }
-    }
-    break;
-    case XT_URL_LINK_TEXT:
-      if (wpt->HasUrlLink()) {
-        UrlLink l = wpt->GetUrlLink();
-        buff = QString().sprintf(fmp.printfc.constData(),
-                 !l.url_link_text_.isEmpty() ? CSTR(l.url_link_text_) : fmp.val.constData());
-      }
-      break;
-    case XT_ICON_DESCR:
-      buff = QString().sprintf(fmp.printfc.constData(),
-                (!wpt->icon_descr.isNull()) ?
-                CSTR(wpt->icon_descr) : fmp.val.constData());
-      break;
-
-      /* LATITUDE CONVERSION***********************************************/
-    case XT_LAT_DECIMAL:
-      /* latitude as a pure decimal value */
-      buff = QString().sprintf(fmp.printfc.constData(), lat);
-      break;
-    case XT_LAT_DECIMALDIR:
-      /* latitude as a decimal value with N/S after it */
-      buff = QString().sprintf(fmp.printfc.constData(), fabs(lat),
-               LAT_DIR(lat));
-      break;
-    case XT_LAT_DIRDECIMAL:
-      /* latitude as a decimal value with N/S before it */
-      buff = QString().sprintf(fmp.printfc.constData(),
-               LAT_DIR(lat),
-               fabs(lat));
-      break;
-    case XT_LAT_INT32DEG:
-      /* latitude as an integer offset from 0 degrees */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                dec_to_intdeg(lat));
-      break;
-    case XT_LAT_DDMMDIR:
-      /*latitude as (degrees * 100) + decimal minutes, with N/S after it */
-      buff = dec_to_human(fmp.printfc.constData(), "SN", degrees2ddmm(lat));
-      break;
-    case XT_LAT_HUMAN_READABLE:
-      buff = dec_to_human(fmp.printfc.constData(), "SN", lat);
-      break;
-    case XT_LAT_NMEA:
-      buff = QString().sprintf(fmp.printfc.constData(), degrees2ddmm(lat));
-      break;
-      // case XT_LAT_10E is handled outside the switch.
-      /* LONGITUDE CONVERSIONS*********************************************/
-    case XT_LON_DECIMAL:
-      /* longitude as a pure decimal value */
-      buff = QString().sprintf(fmp.printfc.constData(), lon);
-      break;
-    case XT_LON_DECIMALDIR:
-      /* latitude as a decimal value with N/S after it */
-      buff = QString().sprintf(fmp.printfc.constData(),
-               fabs(lon),
-               LON_DIR(lon));
-      break;
-    case XT_LON_DIRDECIMAL:
-      /* latitude as a decimal value with N/S before it */
-      buff = QString().sprintf(fmp.printfc.constData(),
-               LON_DIR(lon),
-               fabs(lon));
-      break;
-    case XT_LON_INT32DEG:
-      /* longitudee as an integer offset from 0 degrees */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                dec_to_intdeg(lon));
-      break;
-    case XT_LON_DDMMDIR:
-      /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/
-      buff = dec_to_human(fmp.printfc.constData(), "WE", degrees2ddmm(lon));
-      break;
-    case XT_LON_HUMAN_READABLE:
-      buff = dec_to_human(fmp.printfc.constData(), "WE", lon);
-      break;
-    case XT_LATLON_HUMAN_READABLE:
-      buff = dec_to_human(fmp.printfc.constData(), "SN", lat);
-        buff += " ";
-      buff += dec_to_human(fmp.printfc.constData(), "WE", lon);
-      // Tidy up leading, trailing, middle whitespace.
-      buff = buff.simplified();
-      break;
-    case XT_LON_NMEA:
-      buff = QString().sprintf(fmp.printfc.constData(), degrees2ddmm(lon));
-      break;
-      // case XT_LON_10E is handled outside the switch.
-      /* DIRECTIONS *******************************************************/
-    case XT_LAT_DIR:
-      /* latitude N/S as a char */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                LAT_DIR(lat));
-      break;
-    case XT_LON_DIR:
-      /* longitude E/W as a char */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                LON_DIR(lon));
-      break;
-
-      /* SPECIAL COORDINATES */
-    case XT_MAP_EN_BNG: {
-      char map[3];
-      double north, east;
-      if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map))
-        fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n",
-              wpt->latitude, wpt->longitude);
-      buff = QString().sprintf(fmp.printfc.constData(), map, (int)(east + 0.5), (int)(north + 0.5));
-    }
-    break;
-    case XT_UTM: {
-      char tbuf[100];
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f",
-               utmz, utmzc, utme, utmn);
-      buff = QString().sprintf(fmp.printfc.constData(), tbuf);
-    }
-    break;
-    case XT_UTM_ZONE:
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      buff = QString().sprintf(fmp.printfc.constData(), utmz);
-      break;
-    case XT_UTM_ZONEC:
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      buff = QString().sprintf(fmp.printfc.constData(), utmzc);
-      break;
-    case XT_UTM_ZONEF: {
-      char tbuf[10];
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      tbuf[0] = 0;
-      snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc);
-      buff = QString().sprintf(fmp.printfc.constData(), tbuf);
-    }
-    break;
-    case XT_UTM_NORTHING:
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      buff = QString().sprintf(fmp.printfc.constData(), utmn);
-      break;
-    case XT_UTM_EASTING:
-      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
-                               &utme, &utmn, &utmz, &utmzc);
-      buff = QString().sprintf(fmp.printfc.constData(), utme);
-      break;
-
-      /* ALTITUDE CONVERSIONS**********************************************/
-    case XT_ALT_FEET:
-      /* altitude in feet as a decimal value */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                METERS_TO_FEET(wpt->altitude));
-      break;
-    case XT_ALT_METERS:
-      /* altitude in meters as a decimal value */
-      buff = QString().sprintf(fmp.printfc.constData(),
-                wpt->altitude);
-      break;
-
-      /* DISTANCE CONVERSIONS**********************************************/
-      /* prefer odometer distance. */
-      /* if not available, use calculated distance from positions */
-    case XT_PATH_DISTANCE_MILES:
-      /* path (route/track) distance in miles */
-      if (wpt->odometer_distance) {
-        buff = QString().sprintf(fmp.printfc.constData(), METERS_TO_MILES(wpt->odometer_distance));
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), pathdist);
-      }
-      break;
-    case XT_PATH_DISTANCE_METERS:
-      /* path (route/track) distance in meters */
-      if (wpt->odometer_distance) {
-        buff = QString().sprintf(fmp.printfc.constData(), wpt->odometer_distance);
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist));
-      }
-      break;
-    case XT_PATH_DISTANCE_KM:
-      /* path (route/track) distance in kilometers */
-      if (wpt->odometer_distance) {
-        buff = QString().sprintf(fmp.printfc.constData(), wpt->odometer_distance / 1000.0);
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist) / 1000.0);
-      }
-      break;
-    case XT_PATH_SPEED:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->speed);
-      break;
-    case XT_PATH_SPEED_KPH:
-      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_KPH(wpt->speed));
-      break;
-    case XT_PATH_SPEED_MPH:
-      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_MPH(wpt->speed));
-      break;
-    case XT_PATH_SPEED_KNOTS:
-      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_KNOTS(wpt->speed));
-      break;
-    case XT_PATH_COURSE:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->course);
-      break;
-
-      /* HEART RATE CONVERSION***********************************************/
-    case XT_HEART_RATE:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->heartrate);
-      break;
-      /* CADENCE CONVERSION***********************************************/
-    case XT_CADENCE:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->cadence);
-      break;
-      /* POWER CONVERSION***********************************************/
-    case XT_POWER:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->power);
-      break;
-    case XT_TEMPERATURE:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->temperature);
-      break;
-    case XT_TEMPERATURE_F:
-      buff = QString().sprintf(fmp.printfc.constData(), CELSIUS_TO_FAHRENHEIT(wpt->temperature));
-      break;
-      /* TIME CONVERSIONS**************************************************/
-    case XT_EXCEL_TIME:
-      /* creation time as an excel (double) time */
-      buff = QString().sprintf(fmp.printfc.constData(), TIMET_TO_EXCEL(wpt->GetCreationTime().toTime_t()));
-      break;
-    case XT_TIMET_TIME:
-      /* time as a time_t variable */
-    {
-      time_t tt = wpt->GetCreationTime().toTime_t();
-      buff = QString().sprintf(fmp.printfc.constData(), tt);
-    }
-    break;
-
-    case XT_TIMET_TIME_MS: {
-      /* time as a time_t variable in milliseconds */
-      buff = writetime("%ld", wpt->GetCreationTime().toTime_t(), false);
-      buff += QString().sprintf("%03d", wpt->GetCreationTime().time().msec());
-
-    }
-    break;
-    case XT_YYYYMMDD_TIME:
-      buff = QString().sprintf(fmp.printfc.constData(), time_to_yyyymmdd(wpt->GetCreationTime()));
-      break;
-    case XT_GMT_TIME:
-      buff = writetime(fmp.printfc.constData(), wpt->GetCreationTime(), true);
-      break;
-    case XT_LOCAL_TIME:
-      buff = writetime(fmp.printfc.constData(), wpt->GetCreationTime(), false);
-      break;
-    case XT_HMSG_TIME:
-      buff = writehms(fmp.printfc.constData(), wpt->GetCreationTime(), 1);
-      break;
-    case XT_HMSL_TIME:
-      buff = writehms(fmp.printfc.constData(), wpt->GetCreationTime(), 0);
-      break;
-    case XT_ISO_TIME:
-      buff = writetime("%Y-%m-%dT%H:%M:%SZ", wpt->GetCreationTime(), true);
-      break;
-    case XT_ISO_TIME_MS:
-      buff = wpt->GetCreationTime().toPrettyString();
-      break;
-    case XT_GEOCACHE_LAST_FOUND:
-      buff = QString().sprintf(fmp.printfc.constData(), time_to_yyyymmdd(wpt->gc_data->last_found));
-      break;
-      /* GEOCACHE STUFF **************************************************/
-    case XT_GEOCACHE_DIFF:
-      /* Geocache Difficulty as a double */
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->gc_data->diff / 10.0);
-      field_is_unknown = !wpt->gc_data->diff;
-      break;
-    case XT_GEOCACHE_TERR:
-      /* Geocache Terrain as a double */
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->gc_data->terr / 10.0);
-      field_is_unknown = !wpt->gc_data->terr;
-      break;
-    case XT_GEOCACHE_CONTAINER:
-      /* Geocache Container */
-      buff = QString().sprintf(fmp.printfc.constData(), gs_get_container(wpt->gc_data->container));
-      field_is_unknown = wpt->gc_data->container == gc_unknown;
-      break;
-    case XT_GEOCACHE_TYPE:
-      /* Geocache Type */
-      buff = QString().sprintf(fmp.printfc.constData(), gs_get_cachetype(wpt->gc_data->type));
-      field_is_unknown = wpt->gc_data->type == gt_unknown;
-      break;
-    case XT_GEOCACHE_HINT:
-      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->gc_data->hint));
-      field_is_unknown = !wpt->gc_data->hint.isEmpty();
-      break;
-    case XT_GEOCACHE_PLACER:
-      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->gc_data->placer));
-      field_is_unknown = !wpt->gc_data->placer.isEmpty();
-      break;
-    case XT_GEOCACHE_ISAVAILABLE:
-      if (wpt->gc_data->is_available == status_false) {
-        buff = QString().sprintf(fmp.printfc.constData(), "False");
-      } else if (wpt->gc_data->is_available == status_true) {
-        buff = QString().sprintf(fmp.printfc.constData(), "True");
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), "Unknown");
-      }
-      break;
-    case XT_GEOCACHE_ISARCHIVED:
-      if (wpt->gc_data->is_archived == status_false) {
-        buff = QString().sprintf(fmp.printfc.constData(), "False");
-      } else if (wpt->gc_data->is_archived == status_true) {
-        buff = QString().sprintf(fmp.printfc.constData(), "True");
-      } else {
-        buff = QString().sprintf(fmp.printfc.constData(), "Unknown");
-      }
-      break;
-      /* Tracks and Routes ***********************************************/
-    case XT_TRACK_NEW:
-      if (csv_track) {
-        if (WAYPT_HAS(wpt,new_trkseg)) {
-          buff = QString().sprintf(fmp.printfc.constData(), 1);
-        } else {
-          buff = QString().sprintf(fmp.printfc.constData(), 0);
-        }
-      }
-      break;
-    case XT_TRACK_NAME:
-      if (csv_track) {
-        QString r = csv_track->rte_name;
-        buff = QString().sprintf(fmp.printfc.constData(), NONULL(r));
-      }
-      break;
-    case XT_ROUTE_NAME:
-      if (csv_route) {
-        QString r = csv_route->rte_name;
-        buff = QString().sprintf(fmp.printfc.constData(), NONULL(r));
-      }
-      break;
-
-      /* GPS STUFF *******************************************************/
-    case XT_GPS_HDOP:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->hdop);
-      field_is_unknown = !wpt->hdop;
-      break;
-    case XT_GPS_VDOP:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->vdop);
-      field_is_unknown = !wpt->vdop;
-      break;
-    case XT_GPS_PDOP:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->pdop);
-      field_is_unknown = !wpt->pdop;
-      break;
-    case XT_GPS_SAT:
-      buff = QString().sprintf(fmp.printfc.constData(), wpt->sat);
-      field_is_unknown = !wpt->sat;
-      break;
-    case XT_GPS_FIX: {
-      const char* fix = nullptr;
-      switch (wpt->fix) {
-      case fix_unknown:
-        field_is_unknown = 1;
-        fix = "Unknown";
-        break;
-      case fix_none:
-        fix = "None";
-        break;
-      case fix_2d:
-        fix = "2d";
-        break;
-      case fix_3d:
-        fix = "3d";
-        break;
-      case fix_dgps:
-        fix = "dgps";
-        break;
-      case fix_pps:
-        fix = "pps";
-        break;
-      }
-      buff = QString().sprintf(fmp.printfc.constData(), fix);
-    }
-    break;
-    /* GMSD ************************************************************/
-    case XT_COUNTRY: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(country, ""));
-    }
-    break;
-    case XT_STATE: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(state, ""));
-    }
-    break;
-    case XT_CITY: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(city, ""));
-    }
-    break;
-    case XT_POSTAL_CODE: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(postal_code, ""));
-    }
-    break;
-    case XT_STREET_ADDR: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(addr, ""));
-    }
-    break;
-    case XT_PHONE_NR: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(phone_nr, ""));
-    }
-    break;
-    case XT_FACILITY: {
-      garmin_fs_t* gmsd = GMSD_FIND(wpt);
-      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(facility, ""));
-    }
-    break;
-    /* specials */
-    case XT_FILENAME:
-      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->session->filename));
-      break;
-    case XT_FORMAT:
-      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->session->name));
-      break;
-    case -1:
-      if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
-        buff = QString().sprintf(fmp.printfc.constData(), lon * pow(10.0, atof(fmp.key.constData()+7)));
-      } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
-        buff = QString().sprintf(fmp.printfc.constData(), lat * pow(10.0, atof(fmp.key.constData()+7)));
-      }
-      break;
-    default:
-      warning(MYNAME ": Unknown style directive: %s\n", fmp.key.constData());
-      break;
-    }
-    QString obuff = csv_stringclean(buff, xcsv_file.badchars);
-
-    if (field_is_unknown && fmp.options & OPTIONS_OPTIONAL) {
-      continue;
-    }
-
-    if (!xcsv_file.field_encloser.isEmpty()) {
-      /* print the enclosing character(s) */
-      *xcsv_file.stream << xcsv_file.record_delimiter;
-    }
-
-    /* As a special case (pronounced "horrible hack") we allow
-     * ""%s"" to smuggle bad characters through.
-     */
-    if (0 == strcmp(fmp.printfc.constData(), "\"%s\"")) {
-      obuff = '"' + obuff + '"';
-    }
-    *xcsv_file.stream << obuff;
-
-    if (!xcsv_file.field_encloser.isEmpty()) {
-      /* print the enclosing character(s) */
-      *xcsv_file.stream << xcsv_file.record_delimiter;
-    }
-    buff.clear();
-  }
-
-  *xcsv_file.stream << xcsv_file.record_delimiter;
-
-  /* increment the index counter */
-  waypt_out_count++;
-}
-
-static void
-xcsv_noop(const route_head* wp)
-{
-  (void)wp;
-  /* no-op */
-}
-
-// return |original| after performing token replacement.
-static QString
-xcsv_replace_tokens(const QString& original) {
-  QString replacement = original;
-    // Don't do potentially expensive replacements if token prefix
-    // isn't present;
-    if (original.contains("__")) {
-      time_t my_time = gpsbabel_time;
-
-      replacement.replace("__FILE__", xcsv_file.fname);
-      replacement.replace("__VERSION__", my_time == 0 ? "" : gpsbabel_version);
-
-      QDateTime dt = QDateTime::fromTime_t(my_time);
-      dt = dt.toTimeSpec(Qt::UTC);
-
-      QString dts = dt.toString("ddd MMM dd hh:mm:ss yyyy");
-      replacement.replace("__DATE_AND_TIME__", dts);
-
-      QString d = dt.toString("MM/dd/yyyy");
-      replacement.replace("__DATE__", d);
-
-      QString t = dt.toString("hh:mm:ss");
-      replacement.replace("__TIME__", t);
-    }
-  return replacement;
-}
-
-/*****************************************************************************/
-/* xcsv_data_write(void) - write prologues, spawn the output loop, and write */
-/*                         epilogues.                                        */
-/*****************************************************************************/
-void
-xcsv_data_write()
-{
-  /* reset the index counter */
-  waypt_out_count = 0;
-
-  /* output prologue lines, if any. */
-  for (const auto& line : qAsConst(xcsv_file.prologue)) {
-   QString line_to_write = xcsv_replace_tokens(line);
-    *xcsv_file.stream << line_to_write <<  xcsv_file.record_delimiter;
-  }
-
-  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) {
-    waypt_disp_all(xcsv_waypt_pr);
-  }
-  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) {
-    route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr);
-  }
-  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) {
-    track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr);
-  }
-
-  /* output epilogue lines, if any. */
-  for (const auto& line : qAsConst(xcsv_file.epilogue)) {
-    QString line_to_write = xcsv_replace_tokens(line);
-    *xcsv_file.stream << line_to_write << xcsv_file.record_delimiter;
-  }
-}
-#endif
index b1b5e1d486e559971211c9adef72ac304b5093e9..abcd2d2a5038deca6fe433ffb2dbc185d9d22735 100644 (file)
 
  */
 
-#include "queue.h"
+#ifndef CSV_UTIL_H_INCLUDED_
+#define CSV_UTIL_H_INCLUDED_
+
+#include <QtCore/QString>      // for QString
+
 #include "defs.h"
-#include <QtCore/QStringList>
-class QTextStream;
-#include <utility> 
 
 /* function prototypes */
 
+QString
+csv_stringclean(const QString& source, const QString& to_nuke);
+
 char*
 csv_stringtrim(const char* string, const char* enclosure, int strip_max);
-QString csv_stringtrim(const QString& source, const QString& enclosure);
+QString
+csv_stringtrim(const QString& source, const QString& enclosure);
 
 char*
 csv_lineparse(const char* stringstart, const char* delimited_by, const char* enclosed_in, int line_no);
 
+int
+dec_to_intdeg(const double d);
+
+double
+intdeg_to_dec(const int ideg);
+
+double
+decdir_to_dec(const char* decdir);
+
+double
+ddmmdir_to_degrees(const char* ddmmdir);
+
 void
 human_to_dec(const char* instr, double* outlat, double* outlon, int which);
 inline void
@@ -40,118 +57,7 @@ human_to_dec(const QString& instr, double* outlat, double* outlon, int which) {
   human_to_dec(CSTR(instr), outlat, outlon, which);
 }
 
-char*
-csv_stringclean(const char* string, const char* chararray);
-QString csv_stringclean(const QString& string, const QString& chararray);
-
-void
-xcsv_data_read();
-
-void
-xcsv_data_write();
-
-void
-xcsv_file_init();
-
-void
-xcsv_prologue_add(const QString&);
-
-void
-xcsv_epilogue_add(const QString&);
-
-void
-xcsv_ifield_add(const QString&, const QString&, const QString&);
-
-void
-xcsv_ofield_add(const QString&, const QString&, const QString&, unsigned options);
-
-void
-xcsv_destroy_style();
-
 QString
-xcsv_get_char_from_constant_table(const QString& key);
-
-/****************************************************************************/
-/* types required for various xcsv functions                                */
-/****************************************************************************/
-
-/* something to map fields to waypts */
-#define OPTIONS_NODELIM 1U
-#define OPTIONS_ABSOLUTE 2U
-#define OPTIONS_OPTIONAL 4U
-struct field_map {
-public:
-  // We use QByteArrays because consumers want char* data and QByteArrays supply this through constData().
-  // If we used QStrings, then we would have to convert to QByteArrays to get the char* data.
-  // If we use char* then we have to manage memory allocation/deallocation.
-  // TODO: when consumers use QStrings then we can store QStrings instead of QByteArrays.
-  QByteArray key;
-  QByteArray val;
-  QByteArray printfc;
-  int hashed_key{0};
-  unsigned options{0};
-
-  field_map() = default;
-  field_map(QByteArray k, QByteArray v, QByteArray p, int hk) : key{std::move(k)},val{std::move(v)},printfc{std::move(p)},hashed_key{hk} {}
-  field_map(QByteArray k, QByteArray v, QByteArray p, int hk, unsigned o) : key{std::move(k)},val{std::move(v)},printfc{
-          std::move(p)},hashed_key{hk},options{o} {}
-};
-
-/* something to map config file constants to chars */
-typedef struct char_map {
-  const QString key;
-  const QString chars;
-} char_map_t;
-
-namespace gpsbabel
-{
-    class File;
-}
-/*
- * a Class describing all the wonderful elements of xcsv files, in a
- * nutshell.
- * It completely shows that this began life as a C struct...baby steps.
- */
-class XcsvFile {
- public:
-  XcsvFile();
-
-  bool is_internal;            /* bool - is internal (1) or parsed (0) */
-
-  /* header lines for writing at the top of the file. */
-  QStringList prologue;
-
-  /* footer lines for writing at the bottom of the file. */
-  QStringList epilogue;
-
-  QString field_delimiter;     /* comma, quote, etc... */
-  QString field_encloser;              /* doublequote, etc... */
-  QString record_delimiter;    /* newline, c/r, etc... */
-
-  QString badchars;            /* characters we never write to output */
-
-  QList<field_map> ifields;    /* input field mapping */
-  QList<field_map> ofields;    /* output field mapping */
-
-  gpsbabel::File* file;
-  QTextStream* stream;
-  QTextCodec* codec;
-  QString fname;                 /* ptr to filename of above. */
-
-  QString description;         /* Description for help text */
-  QString extension;           /* preferred filename extension (for wrappers)*/
-
-  short_handle mkshort_handle;/* handle for mkshort() */
-  ff_type type;                /* format type for GUI wrappers. */
-
-  int gps_datum;               /* result of GPS_Lookup_Datum_Index */
-  gpsdata_type datatype;       /* can be wptdata, rtedata or trkdata */
-  /* ... or ZERO to keep the old behaviour */
-
-};
-
+dec_to_human(const char* format, const char* dirs, double val);
 
-/****************************************************************************/
-/* obligatory global struct                                                 */
-/****************************************************************************/
-extern XcsvFile xcsv_file;
+#endif // CSV_UTIL_H_INCLUDED_
diff --git a/defs.h b/defs.h
index e7221ce3a29679620a214caec79913aeaf175cea..8801e75664427c640be6acb8a57383f8523101a0 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -820,9 +820,6 @@ typedef Waypoint* (*ff_readposn)(posn_status*);
 
 char* get_option(const char* iarglist, const char* argname);
 
-void xcsv_setup_internal_style(const char* style_buf);
-void xcsv_read_internal_style(const char* style_buf);
-
 geocache_type gs_mktype(const QString& t);
 geocache_container gs_mkcont(const QString& t);
 
index 52bccf5c9c4acb048b9cc1c1ee6076658b849378..3c2024266e9ae96e4c75a144168a4f5a9b0ecefc 100644 (file)
@@ -17,6 +17,9 @@
 
  */
 
+#ifndef SRC_CORE_FILE_INCLUDED_H_
+#define SRC_CORE_FILE_INCLUDED_H_
+
 #include <QtCore/QFile>
 #include <QtCore/QIODevice>
 #include <cstdio>
@@ -58,3 +61,5 @@ public:
 };
 
 }; // namespace gpsbabel
+
+#endif // SRC_CORE_FILE_INCLUDED_H_
diff --git a/vecs.cc b/vecs.cc
index bd9b6954d89ec248b387d5e8800448b310575fe0..4a72d018b6a5daf4df3c6859bf8bcb7b50a3cb32 100644 (file)
--- a/vecs.cc
+++ b/vecs.cc
@@ -23,6 +23,7 @@
 #include "csv_util.h"
 #include "gbversion.h"
 #include "inifile.h"
+#include "xcsv.h"
 #include <QtCore/QString>
 #include <cstdio>
 #include <cstdlib> // qsort
diff --git a/xcsv.cc b/xcsv.cc
index b1ec2b06eba11f3017e476d2c4ad7cbe2b7a03e8..fba18d3c716cf2772b659b6550df589365829124 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
 
  */
 
-#include <QtCore/QByteArray>   // for QByteArray
-#include <QtCore/QHash>        // for QHash
-#include <QtCore/QString>      // for QString
-#include <QtCore/QStringList>  // for QStringList
-#include <QtCore/QTextCodec>   // for QTextCodec
-#include <QtCore/QTextStream>  // for QTextStream
-#include <QtCore/QtGlobal>     // for qPrintable
-
-#include <cctype>
-#include <cstdlib>
-#include "csv_util.h"
+#include <cctype>                  // for isdigit, tolower
+#include <cmath>                   // for fabs, pow
+#include <cstdio>                  // for snprintf, sscanf
+#include <cstdlib>                 // for atof, atoi, strtod, atol
+#include <cstring>                 // for strlen, strncmp, strcmp, strncpy, memset
+#include <ctime>                   // for gmtime, localtime, mktime, strftime
+
+#include <QtCore/QByteArray>       // for QByteArray
+#include <QtCore/QChar>            // for QChar
+#include <QtCore/QCharRef>         // for QCharRef
+#include <QtCore/QDate>            // for QDate
+#include <QtCore/QDateTime>        // for QDateTime
+#include <QtCore/QFile>            // for QFile
+#include <QtCore/QHash>            // for QHash
+#include <QtCore/QIODevice>        // for operator|, QIODevice::ReadOnly, QIODevice::Text, QIODevice::WriteOnly
+#include <QtCore/QList>            // for QList
+#include <QtCore/QRegExp>          // for QRegExp
+#include <QtCore/QString>          // for QString, operator+, operator==, QByteArray::append
+#include <QtCore/QStringList>      // for QStringList
+#include <QtCore/QTextCodec>       // for QTextCodec
+#include <QtCore/QTextStream>      // for QTextStream
+#include <QtCore/QTime>            // for QTime
+#include <QtCore/Qt>               // for UTC
+#include <QtCore/QtGlobal>         // for qAsConst, QAddConst<>::Type, qPrintable
+
 #include "defs.h"
-#include "jeeps/gpsmath.h"
-#include "src/core/file.h"
-#include "src/core/logging.h"
+#include "csv_util.h"              // for csv_stringtrim, dec_to_human, csv_stringclean, csv_lineparse, human_to_dec, ddmmdir_to_degrees, dec_to_intdeg, decdir_to_dec, intdeg_to_dec
+#include "garmin_fs.h"             // for garmin_fs_t, garmin_fs_flags_t, GMSD_FIND, GMSD_GET, GMSD_SET, garmin_fs_alloc
+#include "gbfile.h"                // for gbfgetstr, gbfclose, gbfopen, gbfile
+#include "grtcirc.h"               // for RAD, gcdist, radtomiles
+#include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN, GPS_Lookup_Datum_Index, GPS_Math_Known_Datum_To_WGS84_M, GPS_Math_UTM_EN_To_Known_Datum, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_WGS84_To_UKOSMap_M
+#include "jeeps/gpsport.h"         // for int32
+#include "session.h"               // for session_t
+#include "src/core/datetime.h"     // for DateTime
+#include "src/core/file.h"         // for File
+#include "src/core/logging.h"      // for Warning, Fatal
+#include "src/core/optional.h"     // for optional
+#include "strptime.h"              // for strptime
+#include "xcsv.h"
 
-#if CSVFMTS_ENABLED
 #define MYNAME "XCSV"
 
+/* macros */
+#define LAT_DIR(a) a < 0.0 ? 'S' : 'N'
+#define LON_DIR(a) a < 0.0 ? 'W' : 'E'
+#define NONULL(a) a.isNull() ? "" : CSTRc(a)
+
+/* convert excel time (days since 1900) to time_t and back again */
+#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0)
+#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0)
+
+#define GPS_DATUM_WGS84                118
+
+
+/*
+ * Internal numeric value to associate with each keyword in a style file.
+ * To add new keywords, just add an entry here, handle it in the switch
+ * statements below, add it to xcsv_tokens.in, and rebuild on a system
+ * that has GNU gperf on it.
+ */
+typedef enum {
+  XT_unused = 0,
+  XT_ALT_FEET,
+  XT_ALT_METERS,
+  XT_ANYNAME,
+  XT_CADENCE,
+  XT_CITY,
+  XT_CONSTANT,
+  XT_COUNTRY,
+  XT_DESCRIPTION,
+  XT_EXCEL_TIME,
+  XT_FACILITY,
+  XT_FILENAME,
+  XT_FORMAT,
+  XT_GEOCACHE_CONTAINER,
+  XT_GEOCACHE_DIFF,
+  XT_GEOCACHE_HINT,
+  XT_GEOCACHE_LAST_FOUND,
+  XT_GEOCACHE_PLACER,
+  XT_GEOCACHE_TERR,
+  XT_GEOCACHE_TYPE,
+  XT_GEOCACHE_ISAVAILABLE,
+  XT_GEOCACHE_ISARCHIVED,
+  XT_GMT_TIME,
+  XT_GPS_FIX,
+  XT_GPS_HDOP,
+  XT_GPS_PDOP,
+  XT_GPS_SAT,
+  XT_GPS_VDOP,
+  XT_HEART_RATE,
+  XT_HMSG_TIME,
+  XT_HMSL_TIME,
+  XT_ICON_DESCR,
+  XT_IGNORE,
+  XT_INDEX,
+  XT_ISO_TIME,
+  XT_ISO_TIME_MS,
+  XT_LATLON_HUMAN_READABLE,
+  XT_LAT_DECIMAL,
+  XT_LAT_DECIMALDIR,
+  XT_LAT_DIR,
+  XT_LAT_DIRDECIMAL,
+  XT_LAT_HUMAN_READABLE,
+  XT_LAT_INT32DEG,
+  XT_LAT_DDMMDIR,
+  XT_LAT_NMEA,
+  XT_LOCAL_TIME,
+  XT_LON_DECIMAL,
+  XT_LON_DECIMALDIR,
+  XT_LON_DIR,
+  XT_LON_DIRDECIMAL,
+  XT_LON_HUMAN_READABLE,
+  XT_LON_INT32DEG,
+  XT_LON_DDMMDIR,
+  XT_LON_NMEA,
+  XT_MAP_EN_BNG,
+  XT_NOTES,
+  XT_NET_TIME,
+  XT_PATH_COURSE,
+  XT_PATH_DISTANCE_KM,
+  XT_PATH_DISTANCE_METERS,
+  XT_PATH_DISTANCE_MILES,
+  XT_PATH_SPEED,
+  XT_PATH_SPEED_KNOTS,
+  XT_PATH_SPEED_KPH,
+  XT_PATH_SPEED_MPH,
+  XT_PHONE_NR,
+  XT_POSTAL_CODE,
+  XT_POWER,
+  XT_ROUTE_NAME,
+  XT_SHORTNAME,
+  XT_STATE,
+  XT_STREET_ADDR,
+  XT_TEMPERATURE,
+  XT_TEMPERATURE_F,
+  XT_TIMET_TIME,
+  XT_TIMET_TIME_MS,
+  XT_TRACK_NAME,
+  XT_TRACK_NEW,
+  XT_URL,
+  XT_UTM,
+  XT_UTM_ZONE,
+  XT_UTM_ZONEC,
+  XT_UTM_ZONEF,
+  XT_UTM_EASTING,
+  XT_UTM_NORTHING,
+  XT_URL_LINK_TEXT,
+  XT_YYYYMMDD_TIME
+} xcsv_token;
+
+#include "xcsv_tokens.gperf"       // for Perfect_Hash, xt_mapping
+
+#if CSVFMTS_ENABLED
+/****************************************************************************/
+/* obligatory global struct                                                 */
+/****************************************************************************/
+
+extern char* xcsv_urlbase;
+extern char* prefer_shortnames;
+
+XcsvFile xcsv_file;
+static double pathdist = 0;
+static double oldlon = 999;
+static double oldlat = 999;
+
+static int waypt_out_count;
+static route_head* csv_track, *csv_route;
+
+struct xcsv_parse_data {
+  QString rte_name;
+  QString trk_name;
+  bool new_track{false};
+  double utm_northing{0};
+  double utm_easting{0};
+  double utm_zone{0};
+  char utm_zonec{'N'};
+  UrlLink* link_{nullptr};
+  gpsbabel_optional::optional<bool> lat_dir_positive;
+  gpsbabel_optional::optional<bool> lon_dir_positive;
+};
+
 static char* styleopt = nullptr;
 static char* snlenopt = nullptr;
 static char* snwhiteopt = nullptr;
@@ -91,6 +253,12 @@ arglist_t xcsv_args[] = {
   ARG_TERMINATOR
 };
 
+/* something to map config file constants to chars */
+typedef struct char_map {
+  const QString key;
+  const QString chars;
+} char_map_t;
+
 /* a table of config file constants mapped to chars */
 static
 char_map_t xcsv_char_table[] = {
@@ -111,7 +279,7 @@ char_map_t xcsv_char_table[] = {
   { nullptr,           nullptr }
 };
 
-void
+static void
 xcsv_destroy_style()
 {
 
@@ -145,7 +313,7 @@ xcsv_destroy_style()
 }
 
 // Given a keyword of "COMMASPACE", return ", ".
-QString
+static QString
 xcsv_get_char_from_constant_table(const QString& key)
 {
   static QHash<QString, QString> substitutions;
@@ -170,6 +338,1513 @@ static QString dequote(const QString& in) {
   return r;
 }
 
+/*****************************************************************************/
+/* xcsv_file_init() - prepare xcsv_file for first use.                       */
+/*****************************************************************************/
+void xcsv_file_init()
+{
+  xcsv_file.is_internal = false;
+  xcsv_file.field_delimiter = QString();
+  xcsv_file.field_encloser = QString();
+  xcsv_file.record_delimiter = QString();
+  xcsv_file.badchars = QString();
+  xcsv_file.file = nullptr;
+  xcsv_file.stream = nullptr;
+  xcsv_file.codec = nullptr;
+  xcsv_file.fname = QString();
+  xcsv_file.description = nullptr;
+  xcsv_file.extension = nullptr;
+
+  xcsv_file.prologue.clear();
+  xcsv_file.epilogue.clear();
+
+  xcsv_file.ifields.clear();
+  xcsv_file.ofields.clear();
+  /*
+   * Provide a sane default for CSV _files_.
+   */
+  xcsv_file.type = ff_type_file;
+
+  xcsv_file.mkshort_handle = mkshort_new_handle();
+  xcsv_file.gps_datum = GPS_DATUM_WGS84;
+}
+
+XcsvFile::XcsvFile() {
+  is_internal = false;
+  extension  = nullptr;
+//   xcsv_file_init();
+}
+
+static void validate_fieldmap(const field_map& fmp, bool is_output) {
+  if (fmp.key.isEmpty()) {
+    Fatal() << MYNAME << ": xcsv style is missing" <<
+            (is_output ? "output" : "input") << "field type.";
+  }
+  if (fmp.val.isNull()) {
+    Fatal() << MYNAME << ": xcsv style" << fmp.key.constData() << "is missing default.";
+  }
+  if (is_output && fmp.printfc.isNull()) {
+    Fatal() << MYNAME << ": xcsv style" << fmp.key.constData() << "output is missing format specifier.";
+  }
+}
+
+/*****************************************************************************/
+/* xcsv_ifield_add() - add input field to ifield queue.                      */
+/* usage: xcsv_ifield_add("DESCRIPTION", "", "%s")                           */
+/*****************************************************************************/
+static void
+xcsv_ifield_add(const QString& qkey, const QString& qval, const QString& qpfc)
+{
+  QByteArray key = qkey.toUtf8();
+  QByteArray val = qval.toUtf8();
+  QByteArray pfc = qpfc.toUtf8();
+
+  struct xt_mapping* xm = Perfect_Hash::in_word_set(key.constData(), strlen(key.constData()));
+
+  field_map fmp(key, val, pfc, xm ? xm->xt_token : -1);
+  validate_fieldmap(fmp, false);
+
+  xcsv_file.ifields.append(fmp);
+}
+
+/*****************************************************************************/
+/* xcsv_ofield_add() - add output field to ofield queue.                     */
+/* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf")                      */
+/*****************************************************************************/
+static void
+xcsv_ofield_add(const QString& qkey, const QString& qval, const QString& qpfc, unsigned options)
+{
+  QByteArray key = qkey.toUtf8();
+  QByteArray val = qval.toUtf8();
+  QByteArray pfc = qpfc.toUtf8();
+
+  struct xt_mapping* xm = Perfect_Hash::in_word_set(key.constData(), strlen(key.constData()));
+
+  field_map fmp(key, val, pfc, xm ? xm->xt_token : -1, options);
+  validate_fieldmap(fmp, true);
+
+  xcsv_file.ofields.append(fmp);
+}
+
+/*****************************************************************************/
+/* xcsv_prologue_add() - add prologue line to prologue queue                 */
+/* usage: xcsv_prologue_add("Four score and seven years ago today,")         */
+/*****************************************************************************/
+static void
+xcsv_prologue_add(const QString& prologue)
+{
+  xcsv_file.prologue.append(prologue);
+}
+
+/*****************************************************************************/
+/* xcsv_epilogue_add() - add epilogue line to epilogue queue                 */
+/* usage: xcsv_epilogue_add("shall not perish from the earth.")              */
+/*****************************************************************************/
+static void
+xcsv_epilogue_add(const QString& epilogue)
+{
+  xcsv_file.epilogue.append(epilogue);
+}
+
+static
+QDateTime
+yyyymmdd_to_time(const char* s)
+{
+  QDate d = QDate::fromString(s, "yyyyMMdd");
+  return QDateTime(d);
+}
+
+
+/*
+ * sscanftime - Parse a date buffer using strftime format
+ */
+static
+time_t
+sscanftime(const char* s, const char* format, const int gmt)
+{
+  struct tm stm;
+  memset(&stm, 0, sizeof(stm));
+
+  if (strptime(s, format, &stm)) {
+    if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) {
+      stm.tm_mday = 1;
+      stm.tm_mon = 0;
+      stm.tm_year = 70;
+    }
+    stm.tm_isdst = -1;
+    if (gmt) {
+      return mkgmtime(&stm);
+    } else {
+      return mktime(&stm);
+    }
+  }
+  // Don't fuss for empty strings.
+  if (*s) {
+    warning("date parse of string '%s' with format '%s' failed.\n",
+            s, format);
+  }
+  return 0;
+}
+
+static
+time_t
+addhms(const char* s, const char* format)
+{
+  time_t tt = 0;
+  int hour = 0;
+  int min = 0;
+  int sec = 0;
+
+  char* ampm = (char*) xmalloc(strlen(s) + 1);
+  int ac = sscanf(s, format, &hour, &min, &sec, ampm);
+  /* If no time format in arg string, assume AM */
+  if (ac < 4) {
+    ampm[0] = 0;
+  }
+  if (ac) {
+    tt = ((tolower(ampm[0])=='p') ? 43200 : 0) + 3600 * hour + 60 * min + sec;
+  }
+  xfree(ampm);
+
+  return tt;
+}
+
+static
+QString
+writetime(const char* format, time_t t, bool gmt)
+{
+  static struct tm* stmp;
+
+  if (gmt) {
+    stmp = gmtime(&t);
+  } else {
+    stmp = localtime(&t);
+  }
+
+  // It's unfortunate that we publish the definition of "strftime specifiers"
+  // in the style definitions.  For this reason, we have to bust everything
+  // down to a time_t and then let strftime handle them.
+
+  char tbuff[1024];
+  strftime(tbuff, sizeof tbuff, format, stmp);
+  return QString(tbuff);
+}
+
+static
+QString
+writetime(const char* format, const gpsbabel::DateTime& t, bool gmt)
+{
+  return writetime(format, t.toTime_t(), gmt);
+}
+
+QString
+writehms(const char* format, time_t t, int gmt)
+{
+  static struct tm no_time = tm();
+  static struct tm* stmp = &no_time;
+
+  if (gmt) {
+    stmp = gmtime(&t);
+  } else {
+    stmp = localtime(&t);
+  }
+
+  if (stmp == nullptr) {
+    stmp = &no_time;
+  }
+
+  return QString().sprintf(format,
+                            stmp->tm_hour, stmp->tm_min, stmp->tm_sec,
+                            (stmp->tm_hour >= 12 ? "PM" : "AM"));
+}
+
+QString
+writehms(const char* format, const gpsbabel::DateTime& t, int gmt)
+{
+  return writehms(format, t.toTime_t(), gmt);
+}
+
+static
+long
+time_to_yyyymmdd(const QDateTime& t)
+{
+  QDate d = t.date();
+  return d.year() * 10000 + d.month() * 100 + d.day();
+}
+
+static garmin_fs_t*
+gmsd_init(Waypoint* wpt)
+{
+  garmin_fs_t* gmsd = GMSD_FIND(wpt);
+  if (gmsd == nullptr) {
+    gmsd = garmin_fs_alloc(-1);
+    fs_chain_add(&wpt->fs, (format_specific_data*) gmsd);
+  }
+  return gmsd;
+}
+
+/*****************************************************************************/
+/* xcsv_parse_val() - parse incoming data into the waypt structure.          */
+/* usage: xcsv_parse_val("-123.34", *waypt, *field_map)                      */
+/*****************************************************************************/
+static void 
+xcsv_parse_val(const char* s, Waypoint* wpt, const field_map& fmp,
+               xcsv_parse_data* parse_data, const int line_no)
+{
+  const char* enclosure = "";
+  geocache_data* gc_data = nullptr;
+
+  if (fmp.printfc.isNull()) {
+    fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp.key.constData());
+  }
+
+  if (0 == strcmp(fmp.printfc.constData(), "\"%s\"")) {
+    enclosure = "\"";
+  }
+  switch (fmp.hashed_key) {
+  case XT_IGNORE:
+    /* IGNORE -- Categorically ignore this... */
+    break;
+  case XT_CONSTANT:
+    /* CONSTANT -- Ignore on Input... */
+    break;
+  case XT_ANYNAME:
+    /* ANYNAME -- Ignore -- this is output magic. */
+    break;
+  case XT_INDEX:
+    /* IGNORE -- Calculated Sequence # For Ouput*/
+    break;
+  case XT_SHORTNAME:
+    wpt->shortname = csv_stringtrim(s, enclosure);
+    break;
+  case XT_DESCRIPTION:
+    wpt->description = csv_stringtrim(s, enclosure);
+    break;
+  case XT_NOTES:
+    wpt->notes = csv_stringtrim(s, "");
+    break;
+  case XT_URL:
+    if (!parse_data->link_) {
+      parse_data->link_ = new UrlLink;
+    }
+    parse_data->link_->url_ = QString(s).trimmed();
+    break;
+  case XT_URL_LINK_TEXT:
+    if (!parse_data->link_) {
+      parse_data->link_ = new UrlLink;
+    }
+    parse_data->link_->url_link_text_ = QString(s).trimmed();
+    break;
+  case XT_ICON_DESCR:
+    wpt->icon_descr = QString(s).trimmed();
+    break;
+
+    /* LATITUDE CONVERSIONS**************************************************/
+  case XT_LAT_DECIMAL:
+    /* latitude as a pure decimal value */
+    wpt->latitude = atof(s);
+    break;
+  case XT_LAT_DECIMALDIR:
+  case XT_LAT_DIRDECIMAL:
+    /* latitude as a decimal with N/S in it. */
+    wpt->latitude = decdir_to_dec(s);
+    break;
+  case XT_LAT_INT32DEG:
+    /* latitude as a 32 bit integer offset */
+    wpt->latitude = intdeg_to_dec((int) atof(s));
+    break;
+  case XT_LAT_HUMAN_READABLE:
+    human_to_dec(s, &wpt->latitude, &wpt->longitude, 1);
+    break;
+  case XT_LAT_DDMMDIR:
+    wpt->latitude = ddmmdir_to_degrees(s);
+    break;
+  case XT_LAT_NMEA:
+    wpt->latitude = ddmm2degrees(atof(s));
+    break;
+    // XT_LAT_10E is handled outside the switch.
+    /* LONGITUDE CONVERSIONS ***********************************************/
+  case XT_LON_DECIMAL:
+    /* longitude as a pure decimal value */
+    wpt->longitude = atof(s);
+    break;
+  case XT_LON_DECIMALDIR:
+  case XT_LON_DIRDECIMAL:
+    /* longitude as a decimal with N/S in it. */
+    wpt->longitude = decdir_to_dec(s);
+    break;
+  case XT_LON_INT32DEG:
+    /* longitude as a 32 bit integer offset  */
+    wpt->longitude = intdeg_to_dec((int) atof(s));
+    break;
+  case XT_LON_HUMAN_READABLE:
+    human_to_dec(s, &wpt->latitude, &wpt->longitude, 2);
+    break;
+  case XT_LON_DDMMDIR:
+    wpt->longitude = ddmmdir_to_degrees(s);
+    break;
+  case XT_LON_NMEA:
+    wpt->longitude = ddmm2degrees(atof(s));
+    break;
+    // case XT_LON_10E is handled outside the switch.
+    /* LAT AND LON CONVERSIONS ********************************************/
+  case XT_LATLON_HUMAN_READABLE:
+    human_to_dec(s, &wpt->latitude, &wpt->longitude, 0);
+    break;
+    /* DIRECTIONS **********************************************************/
+  case XT_LAT_DIR:
+    /* latitude N/S. */
+    if (*s == 'n' || *s == 'N') {
+      parse_data->lat_dir_positive = true;
+    } else if (*s == 's' || *s == 'S') {
+      parse_data->lat_dir_positive = false;
+    } else {
+      warning("parse of string '%s' on line number %d as LAT_DIR failed.  Expected 'n', 'N', 's' or 'S'.\n", s, line_no);
+    }
+    break;
+  case XT_LON_DIR:
+    /* longitude E/W. */
+    if (*s == 'e' || *s == 'E') {
+      parse_data->lon_dir_positive = true; 
+    } else if (*s == 'w' || *s == 'W') {
+      parse_data->lon_dir_positive = false;
+    } else {
+      warning("parse of string '%s' on line number %d as LON_DIR failed.  Expected 'e', 'E', 'w' or 'W'.\n", s, line_no);
+    }
+    break;
+    /* SPECIAL COORDINATES/GRID */
+  case XT_MAP_EN_BNG:
+    parse_coordinates(s, DATUM_OSGB36, grid_bng,
+                      &wpt->latitude, &wpt->longitude, MYNAME);
+    break;
+  case XT_UTM_ZONE:
+    parse_data->utm_zone = atoi(s);
+    break;
+  case XT_UTM_ZONEC:
+    parse_data->utm_zonec = s[0];
+    break;
+  case XT_UTM_ZONEF:
+    parse_data->utm_zone = atoi(s);
+    parse_data->utm_zonec = s[strlen(s) - 1];
+    break;
+  case XT_UTM_EASTING:
+    parse_data->utm_easting = atof(s);
+    break;
+  case XT_UTM_NORTHING:
+    parse_data->utm_northing = atof(s);
+    break;
+  case XT_UTM: {
+    char* ss;
+    int i = 0;
+
+    parse_data->utm_zone = strtod(s, &ss);
+    parse_data->utm_zonec = ss[i];
+    ss++;
+    parse_data->utm_easting = strtod(ss, &ss);
+    while (*ss && !isdigit(*ss)) {
+      ss++;
+    }
+    parse_data->utm_northing = strtod(ss, nullptr);
+  }
+  break;
+  /* ALTITUDE CONVERSIONS ************************************************/
+  case XT_ALT_FEET: {
+    char *endptr;
+    double val = strtod(s, &endptr);
+    if ((val == 0 && s==endptr)) {
+      wpt->altitude = unknown_alt;
+    } else {
+      wpt->altitude = FEET_TO_METERS(val);
+      if (wpt->altitude < unknown_alt + 1) {
+        wpt->altitude = unknown_alt;
+      }
+    }
+  }
+  break;
+  case XT_ALT_METERS: {
+    char *endptr;
+    double val = strtod(s, &endptr);
+    if ((val == 0 && s==endptr)) {
+      wpt->altitude = unknown_alt;
+    } else {
+      wpt->altitude = val;
+      if (wpt->altitude < unknown_alt + 1) {
+        wpt->altitude = unknown_alt;
+      }
+    }
+  }
+  break;
+
+    /* PATH CONVERSIONS ************************************************/
+  case XT_PATH_SPEED:
+    WAYPT_SET(wpt, speed, atof(s));
+    break;
+  case XT_PATH_SPEED_KPH:
+    WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s)));
+    break;
+  case XT_PATH_SPEED_MPH:
+    WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s)));
+    break;
+  case XT_PATH_SPEED_KNOTS:
+    WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s)));
+    break;
+  case XT_PATH_COURSE:
+    WAYPT_SET(wpt, course, atof(s));
+    break;
+
+    /* TIME CONVERSIONS ***************************************************/
+  case XT_EXCEL_TIME:
+    /* Time as Excel Time  */
+    wpt->SetCreationTime(EXCEL_TO_TIMET(atof(s)));
+    break;
+  case XT_TIMET_TIME:
+    /* Time as time_t */
+    wpt->SetCreationTime((time_t) atol(s));
+    break;
+  case XT_TIMET_TIME_MS: {
+    /* Time as time_t in milliseconds */
+    int s_len = strlen(s);
+    if (s_len < 4) {
+      /* less than 1 epochsecond, an unusual case */
+      wpt->SetCreationTime(0, atoi(s));
+    } else {
+      char buff[32];
+      int off = s_len - 3;
+      strncpy(buff, s, off);
+      buff[off] = '\0';
+      time_t t = (time_t) atol(buff);
+      s += off;
+      strncpy(buff, s, 3);
+      buff[3] = '\0';
+      wpt->SetCreationTime(t, atoi(buff));
+    }
+  }
+  break;
+  case XT_YYYYMMDD_TIME:
+    wpt->SetCreationTime(yyyymmdd_to_time(s));
+    break;
+  case XT_GMT_TIME:
+    wpt->SetCreationTime(sscanftime(s, fmp.printfc.constData(), 1));
+    break;
+  case XT_LOCAL_TIME:
+    if (ugetenv("GPSBABEL_FREEZE_TIME").isNull()) {
+      wpt->creation_time += sscanftime(s, fmp.printfc.constData(), 0);
+    } else {
+      /* Force constant time zone for test */
+      wpt->creation_time += sscanftime(s, fmp.printfc.constData(), 1);
+    }
+    break;
+    /* Useful when time and date are in separate fields
+       GMT / Local offset is handled by the two cases above */
+  case XT_HMSG_TIME:
+  case XT_HMSL_TIME:
+    wpt->creation_time += addhms(s, fmp.printfc.constData());
+    break;
+  case XT_ISO_TIME:
+  case XT_ISO_TIME_MS:
+    wpt->SetCreationTime(xml_parse_time(s));
+    break;
+  case XT_NET_TIME: {
+    fatal("XT_NET_TIME can't have possibly ever worked.");
+//    time_t tt = wpt->GetCreationTime();
+//    dotnet_time_to_time_t(atof(s), &tt, &wpt->microseconds);
+  }
+  break;
+  case XT_GEOCACHE_LAST_FOUND:
+    wpt->AllocGCData()->last_found = yyyymmdd_to_time(s);
+    break;
+
+    /* GEOCACHING STUFF ***************************************************/
+  case XT_GEOCACHE_DIFF:
+    /* Geocache Difficulty as an int */
+    wpt->AllocGCData()->diff = atof(s) * 10;
+    break;
+  case XT_GEOCACHE_TERR:
+    /* Geocache Terrain as an int */
+    wpt->AllocGCData()->terr = atof(s) * 10;
+    break;
+  case XT_GEOCACHE_TYPE:
+    /* Geocache Type */
+    wpt->AllocGCData()->type = gs_mktype(s);
+    break;
+  case XT_GEOCACHE_CONTAINER:
+    wpt->AllocGCData()->container = gs_mkcont(s);
+    break;
+  case XT_GEOCACHE_HINT:
+    wpt->AllocGCData()->hint = QString(s).trimmed();
+    break;
+  case XT_GEOCACHE_PLACER:
+    wpt->AllocGCData()->placer = QString(s).trimmed();
+    break;
+  case XT_GEOCACHE_ISAVAILABLE:
+    gc_data = wpt->AllocGCData();
+    if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
+      gc_data->is_available = status_false;
+    } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
+      gc_data->is_available = status_true;
+    } else {
+      gc_data->is_available = status_unknown;
+    }
+    break;
+  case XT_GEOCACHE_ISARCHIVED:
+    gc_data = wpt->AllocGCData();
+    if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
+      gc_data->is_archived = status_false;
+    } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
+      gc_data->is_archived = status_true;
+    } else {
+      gc_data->is_archived = status_unknown;
+    }
+    break;
+
+    /* GPS STUFF *******************************************************/
+  case XT_GPS_HDOP:
+    wpt->hdop = atof(s);
+    break;
+  case XT_GPS_VDOP:
+    wpt->vdop = atof(s);
+    break;
+  case XT_GPS_PDOP:
+    wpt->pdop = atof(s);
+    break;
+  case XT_GPS_SAT:
+    wpt->sat = atoi(s);
+    break;
+  case XT_GPS_FIX:
+    wpt->fix = (fix_type)(atoi(s)-(fix_type)1);
+    if (wpt->fix < fix_2d) {
+      if (!case_ignore_strcmp(s, "none")) {
+        wpt->fix = fix_none;
+      } else if (!case_ignore_strcmp(s, "dgps")) {
+        wpt->fix = fix_dgps;
+      } else if (!case_ignore_strcmp(s, "pps")) {
+        wpt->fix = fix_pps;
+      } else {
+        wpt->fix = fix_unknown;
+      }
+    }
+    break;
+    /* Tracks and routes *********************************************/
+  case XT_ROUTE_NAME:
+    parse_data->rte_name = csv_stringtrim(s, enclosure);
+    break;
+  case XT_TRACK_NEW:
+    parse_data->new_track = atoi(s);
+    break;
+  case XT_TRACK_NAME:
+    parse_data->trk_name = csv_stringtrim(s, enclosure);
+    break;
+
+    /* OTHER STUFF ***************************************************/
+  case XT_PATH_DISTANCE_METERS:
+    wpt->odometer_distance = atof(s);
+    break;
+  case XT_PATH_DISTANCE_KM:
+    wpt->odometer_distance = atof(s) * 1000.0;
+    break;
+  case XT_PATH_DISTANCE_MILES:
+    wpt->odometer_distance = MILES_TO_METERS(atof(s));
+    break;
+  case XT_HEART_RATE:
+    wpt->heartrate = atoi(s);
+    break;
+  case XT_CADENCE:
+    wpt->cadence = atoi(s);
+    break;
+  case XT_POWER:
+    wpt->power = atof(s);
+    break;
+  case XT_TEMPERATURE:
+    wpt->temperature = atof(s);
+    break;
+  case XT_TEMPERATURE_F:
+    wpt->temperature = (FAHRENHEIT_TO_CELSIUS(atof(s)));
+    break;
+    /* GMSD ****************************************************************/
+  case XT_COUNTRY: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(country, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_STATE: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(state, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_CITY: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(city, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_STREET_ADDR: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(addr, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_POSTAL_CODE: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_PHONE_NR: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case XT_FACILITY: {
+    garmin_fs_t* gmsd = gmsd_init(wpt);
+    GMSD_SET(facility, csv_stringtrim(s, enclosure, 0));
+  }
+  break;
+  case -1:
+    if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
+      wpt->longitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
+    } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
+      wpt->latitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
+    } else {
+      warning(MYNAME ": Unknown style directive: %s\n", fmp.key.constData());
+    }
+    break;
+
+  default:
+    fatal("This can't happen\n");
+    break;
+  }
+}
+
+/*****************************************************************************/
+/* xcsv_data_read() - read input file, parsing lines, fields and handling    */
+/*                   any data conversion (the input meat)                    */
+/*****************************************************************************/
+static void
+xcsv_data_read()
+{
+  int linecount = 0;
+  route_head* rte = nullptr;
+  route_head* trk = nullptr;
+
+  while (true) {
+    QString buff = xcsv_file.stream->readLine();
+    if (buff.isNull()) { 
+      break;
+    }
+    linecount++;
+    /* Whack trailing space; leading space may matter if our field sep
+     * is whitespace and we have leading whitespace.
+     */
+    // This could be hoisted out as a generic rtrim() if we need such a thing.
+    while(buff.size() > 0 && buff.at(buff.size() - 1).isSpace()) {
+      buff.chop(1); 
+    }
+
+    /* skip over x many lines on the top for the prologue... */
+    if ((linecount - 1) < xcsv_file.prologue.count()) {
+      continue;
+    }
+
+    /* We should skip over epilogue lines also.  Since we don't want to
+     * pre-read the file to know how many data lines we should be seeing,
+     * we take this cheap shot at the data and cross our fingers.
+     */
+    for(const auto& ogp : qAsConst(xcsv_file.epilogue)) {
+       if (ogp.startsWith(buff)) {
+         buff.clear();
+         break;
+       }
+    }
+    if (!buff.isEmpty()) {
+      Waypoint* wpt_tmp = new Waypoint;
+      // initialize parse data for accumulation of line results from all fields in this line.
+      xcsv_parse_data parse_data;
+      // tbuf is a temporary copy of buff since we modify it. :-(
+      char *tbuf = xstrdup(buff);
+      const char* s = tbuf;
+      s = csv_lineparse(s, CSTR(xcsv_file.field_delimiter),
+                        CSTR(xcsv_file.field_encloser), linecount);
+
+      if (xcsv_file.ifields.isEmpty()) {
+        fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", CSTR(xcsv_file.description)? CSTR(xcsv_file.description) : "unknown");
+      }
+
+      int ifield_idx = 0;
+
+      /* now rip the line apart, advancing the queue for each tear
+       * off the beginning of buff since there's no index into queue.
+       */
+      while (s) {
+        const field_map& fmp = xcsv_file.ifields.at(ifield_idx++);
+        xcsv_parse_val(s, wpt_tmp, fmp, &parse_data, linecount);
+
+        if (ifield_idx >= xcsv_file.ifields.size()) {
+          /* we've wrapped the queue. so stop parsing! */
+          while (s) {
+            s = csv_lineparse(nullptr, "\xff","",linecount);
+          }
+          break;
+        }
+
+        s = csv_lineparse(nullptr, CSTR(xcsv_file.field_delimiter),
+                          CSTR(xcsv_file.field_encloser), linecount);
+      }
+
+      // If XT_LAT_DIR(XT_LON_DIR) was an input field, and the latitude(longitude) is positive,
+      // assume the latitude(longitude) was the absolute value and take the sign from XT_LAT_DIR(XT_LON_DIR).
+      if (parse_data.lat_dir_positive.has_value() && !parse_data.lat_dir_positive.value() && (wpt_tmp->latitude > 0.0)) {
+        wpt_tmp->latitude = -wpt_tmp->latitude;
+      }
+      if (parse_data.lon_dir_positive.has_value() && !parse_data.lon_dir_positive.value() && (wpt_tmp->longitude > 0.0)) {
+        wpt_tmp->longitude = -wpt_tmp->longitude;
+      }
+
+      if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) {
+        double alt;
+        GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0,
+                                        &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum);
+      }
+
+      if (parse_data.utm_easting || parse_data.utm_northing) {
+        GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude,
+                                       &wpt_tmp->longitude,
+                                       parse_data.utm_easting, parse_data.utm_northing,
+                                       parse_data.utm_zone, parse_data.utm_zonec,
+                                       DATUM_WGS84);
+      }
+
+      if (parse_data.link_) {
+        wpt_tmp->AddUrlLink(*parse_data.link_);
+        delete parse_data.link_;
+        parse_data.link_ = nullptr;
+      }
+
+      switch (xcsv_file.datatype) {
+      case unknown_gpsdata:
+      case wptdata:
+        waypt_add(wpt_tmp);
+        break;
+      case trkdata:
+        if ((trk == nullptr) || parse_data.new_track) {
+          trk = route_head_alloc();
+          track_add_head(trk);
+        }
+        if (!parse_data.trk_name.isEmpty()) {
+          trk->rte_name = parse_data.trk_name;
+        }
+        track_add_wpt(trk, wpt_tmp);
+        break;
+      case rtedata:
+        if (rte == nullptr) {
+          rte = route_head_alloc();
+          route_add_head(rte);
+        }
+        if (!parse_data.rte_name.isEmpty()) {
+          rte->rte_name = parse_data.rte_name;
+        }
+        route_add_wpt(rte, wpt_tmp);
+        break;
+      default:
+        ;
+      }
+      xfree(tbuf);
+    }
+  }
+}
+
+static void
+xcsv_resetpathlen(const route_head* head)
+{
+  pathdist = 0;
+  oldlat = 999;
+  oldlon = 999;
+  csv_route = csv_track = nullptr;
+  switch (xcsv_file.datatype) {
+  case trkdata:
+    csv_track = const_cast<route_head*>(head);
+    break;
+  case rtedata:
+    csv_route = const_cast<route_head*>(head);
+    break;
+  default:
+    break;
+  }
+}
+
+/*****************************************************************************/
+/* xcsv_waypt_pr() - write output file, handling output conversions          */
+/*                  (the output meat)                                        */
+/*****************************************************************************/
+static void
+xcsv_waypt_pr(const Waypoint* wpt)
+{
+  QString buff;
+  double latitude, longitude;
+  int32 utmz;
+  double utme, utmn;
+  char utmzc;
+
+  buff[0] = '\0';
+
+  if (oldlon < 900) {
+    pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon),
+                                  RAD(wpt->latitude),RAD(wpt->longitude)));
+  }
+  longitude = oldlon = wpt->longitude;
+  latitude = oldlat = wpt->latitude;
+
+  QString write_delimiter;
+  if (xcsv_file.field_delimiter == "\\w") {
+    write_delimiter = " ";
+  } else {
+    write_delimiter = xcsv_file.field_delimiter;
+  }
+
+  QString description;
+  QString shortname;
+  if (wpt->shortname.isEmpty() || global_opts.synthesize_shortnames) {
+    if (!wpt->description.isEmpty()) {
+      if (global_opts.synthesize_shortnames) {
+        shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt);
+      } else {
+        shortname = csv_stringclean(wpt->description, xcsv_file.badchars);
+      }
+    } else {
+      /* no shortname available -- let shortname default on output */
+    }
+  } else {
+    shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars);
+  }
+  if (wpt->description.isEmpty()) {
+    if (!shortname.isEmpty()) {
+      description = csv_stringclean(shortname, xcsv_file.badchars);
+    } else {
+      /* no description -- let description default on output */
+    }
+  } else {
+    description = csv_stringclean(wpt->description, xcsv_file.badchars);
+  }
+
+  if (prefer_shortnames) {
+    description = shortname;
+  }
+
+  if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) {
+    double alt;
+    GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0,
+                                    &latitude, &longitude, &alt, xcsv_file.gps_datum);
+  }
+
+  int i = 0;
+  for (const auto& fmp : qAsConst(xcsv_file.ofields)) {
+    double lat = latitude;
+    double lon = longitude;
+    /*
+     * A klunky concept.   This should evaluate to true for any
+     * field if we think we don't have realistic value for it.
+     * This is used by the 'optional' attribute for suppressing
+     * fields on output.
+     */
+    int field_is_unknown = 0;
+
+    if ((i != 0) && !(fmp.options & OPTIONS_NODELIM)) {
+      *xcsv_file.stream << write_delimiter;
+    }
+
+    if (fmp.options & OPTIONS_ABSOLUTE) {
+      lat = fabs(lat);
+      lon = fabs(lon);
+    }
+
+    i++;
+
+    switch (fmp.hashed_key) {
+    case XT_IGNORE:
+      /* IGNORE -- Write the char printf conversion */
+      buff = QString().sprintf(fmp.printfc.constData(), "");
+      break;
+    case XT_INDEX:
+      buff = QString().sprintf(fmp.printfc.constData(), waypt_out_count + atoi(fmp.val.constData()));
+      break;
+    case XT_CONSTANT: {
+      auto cp = xcsv_get_char_from_constant_table(fmp.val.constData());
+      if (!cp.isEmpty()) {
+        buff = QString().sprintf(fmp.printfc.constData(), CSTR(cp));
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), fmp.val.constData());
+      }
+    }
+    break;
+    case XT_SHORTNAME:
+               buff = QString().sprintf(fmp.printfc.constData(),
+                shortname.isEmpty() ? fmp.val.constData() : CSTR(shortname));
+
+      break;
+    case XT_ANYNAME:
+      {
+      QString anyname = wpt->shortname;
+      if (anyname.isEmpty()) {
+        anyname = mkshort(xcsv_file.mkshort_handle, wpt->description);
+      }
+      if (anyname.isEmpty()) {
+        anyname = mkshort(xcsv_file.mkshort_handle, wpt->description);
+      }
+      if (anyname.isEmpty()) {
+        anyname = wpt->notes;
+      }
+      if (anyname.isEmpty()) {
+        anyname = fmp.val.constData();
+      }
+      buff = QString().sprintf(fmp.printfc.constData(), CSTR(anyname));
+      }
+
+      break;
+    case XT_DESCRIPTION:
+      buff = QString().sprintf(fmp.printfc.constData(),
+                description.isEmpty() ? fmp.val.constData() : CSTR(description));
+      break;
+    case XT_NOTES:
+      buff = QString().sprintf(fmp.printfc.constData(),
+                wpt->notes.isEmpty() ? fmp.val.constData() : CSTR(wpt->notes));
+      break;
+    case XT_URL: {
+      if (xcsv_urlbase) {
+        buff = xcsv_urlbase;
+      }
+      if (wpt->HasUrlLink()) {
+        UrlLink l = wpt->GetUrlLink();
+        buff += QString().sprintf(fmp.printfc.constData(), CSTR(l.url_));
+      } else {
+        buff += QString().sprintf(fmp.printfc.constData(), fmp.val.constData() && *fmp.val.constData() ? fmp.val.constData() : "\"\"");
+      }
+    }
+    break;
+    case XT_URL_LINK_TEXT:
+      if (wpt->HasUrlLink()) {
+        UrlLink l = wpt->GetUrlLink();
+        buff = QString().sprintf(fmp.printfc.constData(),
+                 !l.url_link_text_.isEmpty() ? CSTR(l.url_link_text_) : fmp.val.constData());
+      }
+      break;
+    case XT_ICON_DESCR:
+      buff = QString().sprintf(fmp.printfc.constData(),
+                (!wpt->icon_descr.isNull()) ?
+                CSTR(wpt->icon_descr) : fmp.val.constData());
+      break;
+
+      /* LATITUDE CONVERSION***********************************************/
+    case XT_LAT_DECIMAL:
+      /* latitude as a pure decimal value */
+      buff = QString().sprintf(fmp.printfc.constData(), lat);
+      break;
+    case XT_LAT_DECIMALDIR:
+      /* latitude as a decimal value with N/S after it */
+      buff = QString().sprintf(fmp.printfc.constData(), fabs(lat),
+               LAT_DIR(lat));
+      break;
+    case XT_LAT_DIRDECIMAL:
+      /* latitude as a decimal value with N/S before it */
+      buff = QString().sprintf(fmp.printfc.constData(),
+               LAT_DIR(lat),
+               fabs(lat));
+      break;
+    case XT_LAT_INT32DEG:
+      /* latitude as an integer offset from 0 degrees */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                dec_to_intdeg(lat));
+      break;
+    case XT_LAT_DDMMDIR:
+      /*latitude as (degrees * 100) + decimal minutes, with N/S after it */
+      buff = dec_to_human(fmp.printfc.constData(), "SN", degrees2ddmm(lat));
+      break;
+    case XT_LAT_HUMAN_READABLE:
+      buff = dec_to_human(fmp.printfc.constData(), "SN", lat);
+      break;
+    case XT_LAT_NMEA:
+      buff = QString().sprintf(fmp.printfc.constData(), degrees2ddmm(lat));
+      break;
+      // case XT_LAT_10E is handled outside the switch.
+      /* LONGITUDE CONVERSIONS*********************************************/
+    case XT_LON_DECIMAL:
+      /* longitude as a pure decimal value */
+      buff = QString().sprintf(fmp.printfc.constData(), lon);
+      break;
+    case XT_LON_DECIMALDIR:
+      /* latitude as a decimal value with N/S after it */
+      buff = QString().sprintf(fmp.printfc.constData(),
+               fabs(lon),
+               LON_DIR(lon));
+      break;
+    case XT_LON_DIRDECIMAL:
+      /* latitude as a decimal value with N/S before it */
+      buff = QString().sprintf(fmp.printfc.constData(),
+               LON_DIR(lon),
+               fabs(lon));
+      break;
+    case XT_LON_INT32DEG:
+      /* longitudee as an integer offset from 0 degrees */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                dec_to_intdeg(lon));
+      break;
+    case XT_LON_DDMMDIR:
+      /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/
+      buff = dec_to_human(fmp.printfc.constData(), "WE", degrees2ddmm(lon));
+      break;
+    case XT_LON_HUMAN_READABLE:
+      buff = dec_to_human(fmp.printfc.constData(), "WE", lon);
+      break;
+    case XT_LATLON_HUMAN_READABLE:
+      buff = dec_to_human(fmp.printfc.constData(), "SN", lat);
+        buff += " ";
+      buff += dec_to_human(fmp.printfc.constData(), "WE", lon);
+      // Tidy up leading, trailing, middle whitespace.
+      buff = buff.simplified();
+      break;
+    case XT_LON_NMEA:
+      buff = QString().sprintf(fmp.printfc.constData(), degrees2ddmm(lon));
+      break;
+      // case XT_LON_10E is handled outside the switch.
+      /* DIRECTIONS *******************************************************/
+    case XT_LAT_DIR:
+      /* latitude N/S as a char */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                LAT_DIR(lat));
+      break;
+    case XT_LON_DIR:
+      /* longitude E/W as a char */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                LON_DIR(lon));
+      break;
+
+      /* SPECIAL COORDINATES */
+    case XT_MAP_EN_BNG: {
+      char map[3];
+      double north, east;
+      if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map))
+        fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n",
+              wpt->latitude, wpt->longitude);
+      buff = QString().sprintf(fmp.printfc.constData(), map, (int)(east + 0.5), (int)(north + 0.5));
+    }
+    break;
+    case XT_UTM: {
+      char tbuf[100];
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f",
+               utmz, utmzc, utme, utmn);
+      buff = QString().sprintf(fmp.printfc.constData(), tbuf);
+    }
+    break;
+    case XT_UTM_ZONE:
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      buff = QString().sprintf(fmp.printfc.constData(), utmz);
+      break;
+    case XT_UTM_ZONEC:
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      buff = QString().sprintf(fmp.printfc.constData(), utmzc);
+      break;
+    case XT_UTM_ZONEF: {
+      char tbuf[10];
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      tbuf[0] = 0;
+      snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc);
+      buff = QString().sprintf(fmp.printfc.constData(), tbuf);
+    }
+    break;
+    case XT_UTM_NORTHING:
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      buff = QString().sprintf(fmp.printfc.constData(), utmn);
+      break;
+    case XT_UTM_EASTING:
+      GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
+                               &utme, &utmn, &utmz, &utmzc);
+      buff = QString().sprintf(fmp.printfc.constData(), utme);
+      break;
+
+      /* ALTITUDE CONVERSIONS**********************************************/
+    case XT_ALT_FEET:
+      /* altitude in feet as a decimal value */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                METERS_TO_FEET(wpt->altitude));
+      break;
+    case XT_ALT_METERS:
+      /* altitude in meters as a decimal value */
+      buff = QString().sprintf(fmp.printfc.constData(),
+                wpt->altitude);
+      break;
+
+      /* DISTANCE CONVERSIONS**********************************************/
+      /* prefer odometer distance. */
+      /* if not available, use calculated distance from positions */
+    case XT_PATH_DISTANCE_MILES:
+      /* path (route/track) distance in miles */
+      if (wpt->odometer_distance) {
+        buff = QString().sprintf(fmp.printfc.constData(), METERS_TO_MILES(wpt->odometer_distance));
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), pathdist);
+      }
+      break;
+    case XT_PATH_DISTANCE_METERS:
+      /* path (route/track) distance in meters */
+      if (wpt->odometer_distance) {
+        buff = QString().sprintf(fmp.printfc.constData(), wpt->odometer_distance);
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist));
+      }
+      break;
+    case XT_PATH_DISTANCE_KM:
+      /* path (route/track) distance in kilometers */
+      if (wpt->odometer_distance) {
+        buff = QString().sprintf(fmp.printfc.constData(), wpt->odometer_distance / 1000.0);
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), MILES_TO_METERS(pathdist) / 1000.0);
+      }
+      break;
+    case XT_PATH_SPEED:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->speed);
+      break;
+    case XT_PATH_SPEED_KPH:
+      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_KPH(wpt->speed));
+      break;
+    case XT_PATH_SPEED_MPH:
+      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_MPH(wpt->speed));
+      break;
+    case XT_PATH_SPEED_KNOTS:
+      buff = QString().sprintf(fmp.printfc.constData(), MPS_TO_KNOTS(wpt->speed));
+      break;
+    case XT_PATH_COURSE:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->course);
+      break;
+
+      /* HEART RATE CONVERSION***********************************************/
+    case XT_HEART_RATE:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->heartrate);
+      break;
+      /* CADENCE CONVERSION***********************************************/
+    case XT_CADENCE:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->cadence);
+      break;
+      /* POWER CONVERSION***********************************************/
+    case XT_POWER:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->power);
+      break;
+    case XT_TEMPERATURE:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->temperature);
+      break;
+    case XT_TEMPERATURE_F:
+      buff = QString().sprintf(fmp.printfc.constData(), CELSIUS_TO_FAHRENHEIT(wpt->temperature));
+      break;
+      /* TIME CONVERSIONS**************************************************/
+    case XT_EXCEL_TIME:
+      /* creation time as an excel (double) time */
+      buff = QString().sprintf(fmp.printfc.constData(), TIMET_TO_EXCEL(wpt->GetCreationTime().toTime_t()));
+      break;
+    case XT_TIMET_TIME:
+      /* time as a time_t variable */
+    {
+      time_t tt = wpt->GetCreationTime().toTime_t();
+      buff = QString().sprintf(fmp.printfc.constData(), tt);
+    }
+    break;
+
+    case XT_TIMET_TIME_MS: {
+      /* time as a time_t variable in milliseconds */
+      buff = writetime("%ld", wpt->GetCreationTime().toTime_t(), false);
+      buff += QString().sprintf("%03d", wpt->GetCreationTime().time().msec());
+
+    }
+    break;
+    case XT_YYYYMMDD_TIME:
+      buff = QString().sprintf(fmp.printfc.constData(), time_to_yyyymmdd(wpt->GetCreationTime()));
+      break;
+    case XT_GMT_TIME:
+      buff = writetime(fmp.printfc.constData(), wpt->GetCreationTime(), true);
+      break;
+    case XT_LOCAL_TIME:
+      buff = writetime(fmp.printfc.constData(), wpt->GetCreationTime(), false);
+      break;
+    case XT_HMSG_TIME:
+      buff = writehms(fmp.printfc.constData(), wpt->GetCreationTime(), 1);
+      break;
+    case XT_HMSL_TIME:
+      buff = writehms(fmp.printfc.constData(), wpt->GetCreationTime(), 0);
+      break;
+    case XT_ISO_TIME:
+      buff = writetime("%Y-%m-%dT%H:%M:%SZ", wpt->GetCreationTime(), true);
+      break;
+    case XT_ISO_TIME_MS:
+      buff = wpt->GetCreationTime().toPrettyString();
+      break;
+    case XT_GEOCACHE_LAST_FOUND:
+      buff = QString().sprintf(fmp.printfc.constData(), time_to_yyyymmdd(wpt->gc_data->last_found));
+      break;
+      /* GEOCACHE STUFF **************************************************/
+    case XT_GEOCACHE_DIFF:
+      /* Geocache Difficulty as a double */
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->gc_data->diff / 10.0);
+      field_is_unknown = !wpt->gc_data->diff;
+      break;
+    case XT_GEOCACHE_TERR:
+      /* Geocache Terrain as a double */
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->gc_data->terr / 10.0);
+      field_is_unknown = !wpt->gc_data->terr;
+      break;
+    case XT_GEOCACHE_CONTAINER:
+      /* Geocache Container */
+      buff = QString().sprintf(fmp.printfc.constData(), gs_get_container(wpt->gc_data->container));
+      field_is_unknown = wpt->gc_data->container == gc_unknown;
+      break;
+    case XT_GEOCACHE_TYPE:
+      /* Geocache Type */
+      buff = QString().sprintf(fmp.printfc.constData(), gs_get_cachetype(wpt->gc_data->type));
+      field_is_unknown = wpt->gc_data->type == gt_unknown;
+      break;
+    case XT_GEOCACHE_HINT:
+      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->gc_data->hint));
+      field_is_unknown = !wpt->gc_data->hint.isEmpty();
+      break;
+    case XT_GEOCACHE_PLACER:
+      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->gc_data->placer));
+      field_is_unknown = !wpt->gc_data->placer.isEmpty();
+      break;
+    case XT_GEOCACHE_ISAVAILABLE:
+      if (wpt->gc_data->is_available == status_false) {
+        buff = QString().sprintf(fmp.printfc.constData(), "False");
+      } else if (wpt->gc_data->is_available == status_true) {
+        buff = QString().sprintf(fmp.printfc.constData(), "True");
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), "Unknown");
+      }
+      break;
+    case XT_GEOCACHE_ISARCHIVED:
+      if (wpt->gc_data->is_archived == status_false) {
+        buff = QString().sprintf(fmp.printfc.constData(), "False");
+      } else if (wpt->gc_data->is_archived == status_true) {
+        buff = QString().sprintf(fmp.printfc.constData(), "True");
+      } else {
+        buff = QString().sprintf(fmp.printfc.constData(), "Unknown");
+      }
+      break;
+      /* Tracks and Routes ***********************************************/
+    case XT_TRACK_NEW:
+      if (csv_track) {
+        if (WAYPT_HAS(wpt,new_trkseg)) {
+          buff = QString().sprintf(fmp.printfc.constData(), 1);
+        } else {
+          buff = QString().sprintf(fmp.printfc.constData(), 0);
+        }
+      }
+      break;
+    case XT_TRACK_NAME:
+      if (csv_track) {
+        QString r = csv_track->rte_name;
+        buff = QString().sprintf(fmp.printfc.constData(), NONULL(r));
+      }
+      break;
+    case XT_ROUTE_NAME:
+      if (csv_route) {
+        QString r = csv_route->rte_name;
+        buff = QString().sprintf(fmp.printfc.constData(), NONULL(r));
+      }
+      break;
+
+      /* GPS STUFF *******************************************************/
+    case XT_GPS_HDOP:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->hdop);
+      field_is_unknown = !wpt->hdop;
+      break;
+    case XT_GPS_VDOP:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->vdop);
+      field_is_unknown = !wpt->vdop;
+      break;
+    case XT_GPS_PDOP:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->pdop);
+      field_is_unknown = !wpt->pdop;
+      break;
+    case XT_GPS_SAT:
+      buff = QString().sprintf(fmp.printfc.constData(), wpt->sat);
+      field_is_unknown = !wpt->sat;
+      break;
+    case XT_GPS_FIX: {
+      const char* fix = nullptr;
+      switch (wpt->fix) {
+      case fix_unknown:
+        field_is_unknown = 1;
+        fix = "Unknown";
+        break;
+      case fix_none:
+        fix = "None";
+        break;
+      case fix_2d:
+        fix = "2d";
+        break;
+      case fix_3d:
+        fix = "3d";
+        break;
+      case fix_dgps:
+        fix = "dgps";
+        break;
+      case fix_pps:
+        fix = "pps";
+        break;
+      }
+      buff = QString().sprintf(fmp.printfc.constData(), fix);
+    }
+    break;
+    /* GMSD ************************************************************/
+    case XT_COUNTRY: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(country, ""));
+    }
+    break;
+    case XT_STATE: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(state, ""));
+    }
+    break;
+    case XT_CITY: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(city, ""));
+    }
+    break;
+    case XT_POSTAL_CODE: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(postal_code, ""));
+    }
+    break;
+    case XT_STREET_ADDR: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(addr, ""));
+    }
+    break;
+    case XT_PHONE_NR: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(phone_nr, ""));
+    }
+    break;
+    case XT_FACILITY: {
+      garmin_fs_t* gmsd = GMSD_FIND(wpt);
+      buff = QString().sprintf(fmp.printfc.constData(), GMSD_GET(facility, ""));
+    }
+    break;
+    /* specials */
+    case XT_FILENAME:
+      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->session->filename));
+      break;
+    case XT_FORMAT:
+      buff = QString().sprintf(fmp.printfc.constData(), CSTR(wpt->session->name));
+      break;
+    case -1:
+      if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
+        buff = QString().sprintf(fmp.printfc.constData(), lon * pow(10.0, atof(fmp.key.constData()+7)));
+      } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
+        buff = QString().sprintf(fmp.printfc.constData(), lat * pow(10.0, atof(fmp.key.constData()+7)));
+      }
+      break;
+    default:
+      warning(MYNAME ": Unknown style directive: %s\n", fmp.key.constData());
+      break;
+    }
+    QString obuff = csv_stringclean(buff, xcsv_file.badchars);
+
+    if (field_is_unknown && fmp.options & OPTIONS_OPTIONAL) {
+      continue;
+    }
+
+    if (!xcsv_file.field_encloser.isEmpty()) {
+      /* print the enclosing character(s) */
+      *xcsv_file.stream << xcsv_file.record_delimiter;
+    }
+
+    /* As a special case (pronounced "horrible hack") we allow
+     * ""%s"" to smuggle bad characters through.
+     */
+    if (0 == strcmp(fmp.printfc.constData(), "\"%s\"")) {
+      obuff = '"' + obuff + '"';
+    }
+    *xcsv_file.stream << obuff;
+
+    if (!xcsv_file.field_encloser.isEmpty()) {
+      /* print the enclosing character(s) */
+      *xcsv_file.stream << xcsv_file.record_delimiter;
+    }
+    buff.clear();
+  }
+
+  *xcsv_file.stream << xcsv_file.record_delimiter;
+
+  /* increment the index counter */
+  waypt_out_count++;
+}
+
+static void
+xcsv_noop(const route_head* wp)
+{
+  (void)wp;
+  /* no-op */
+}
+
+// return |original| after performing token replacement.
+static QString
+xcsv_replace_tokens(const QString& original) {
+  QString replacement = original;
+    // Don't do potentially expensive replacements if token prefix
+    // isn't present;
+    if (original.contains("__")) {
+      time_t my_time = gpsbabel_time;
+
+      replacement.replace("__FILE__", xcsv_file.fname);
+      replacement.replace("__VERSION__", my_time == 0 ? "" : gpsbabel_version);
+
+      QDateTime dt = QDateTime::fromTime_t(my_time);
+      dt = dt.toTimeSpec(Qt::UTC);
+
+      QString dts = dt.toString("ddd MMM dd hh:mm:ss yyyy");
+      replacement.replace("__DATE_AND_TIME__", dts);
+
+      QString d = dt.toString("MM/dd/yyyy");
+      replacement.replace("__DATE__", d);
+
+      QString t = dt.toString("hh:mm:ss");
+      replacement.replace("__TIME__", t);
+    }
+  return replacement;
+}
+
+/*****************************************************************************/
+/* xcsv_data_write(void) - write prologues, spawn the output loop, and write */
+/*                         epilogues.                                        */
+/*****************************************************************************/
+static void
+xcsv_data_write()
+{
+  /* reset the index counter */
+  waypt_out_count = 0;
+
+  /* output prologue lines, if any. */
+  for (const auto& line : qAsConst(xcsv_file.prologue)) {
+   QString line_to_write = xcsv_replace_tokens(line);
+    *xcsv_file.stream << line_to_write <<  xcsv_file.record_delimiter;
+  }
+
+  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) {
+    waypt_disp_all(xcsv_waypt_pr);
+  }
+  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) {
+    route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr);
+  }
+  if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) {
+    track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr);
+  }
+
+  /* output epilogue lines, if any. */
+  for (const auto& line : qAsConst(xcsv_file.epilogue)) {
+    QString line_to_write = xcsv_replace_tokens(line);
+    *xcsv_file.stream << line_to_write << xcsv_file.record_delimiter;
+  }
+}
+
 static void
 xcsv_parse_style_line(QString line)
 {
diff --git a/xcsv.h b/xcsv.h
new file mode 100644 (file)
index 0000000..806ff30
--- /dev/null
+++ b/xcsv.h
@@ -0,0 +1,116 @@
+/*
+    Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+    Copyright (C) 2002-2014 Robert Lipe
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#ifndef XCSV_H_INCLUDED_
+#define XCSV_H_INCLUDED_
+
+#include <utility>             // for move
+
+#include <QtCore/QByteArray>   // for QByteArray
+#include <QtCore/QList>        // for QList
+#include <QtCore/QString>      // for QString
+#include <QtCore/QStringList>  // for QStringList
+#include <QtCore/QTextCodec>   // for QTextCodec
+#include <QtCore/QTextStream>  // for QTextStream
+
+#include "defs.h"
+#include "src/core/file.h"     // for File
+
+/* function prototypes */
+
+void xcsv_setup_internal_style(const char* style_buf);
+void xcsv_read_internal_style(const char* style_buf);
+
+/****************************************************************************/
+/* types required for various xcsv functions                                */
+/****************************************************************************/
+
+/* something to map fields to waypts */
+#define OPTIONS_NODELIM 1U
+#define OPTIONS_ABSOLUTE 2U
+#define OPTIONS_OPTIONAL 4U
+struct field_map {
+public:
+  // We use QByteArrays because consumers want char* data and QByteArrays supply this through constData().
+  // If we used QStrings, then we would have to convert to QByteArrays to get the char* data.
+  // If we use char* then we have to manage memory allocation/deallocation.
+  // TODO: when consumers use QStrings then we can store QStrings instead of QByteArrays.
+  QByteArray key;
+  QByteArray val;
+  QByteArray printfc;
+  int hashed_key{0};
+  unsigned options{0};
+
+  field_map() = default;
+  field_map(QByteArray k, QByteArray v, QByteArray p, int hk) : key{std::move(k)},val{std::move(v)},printfc{std::move(p)},hashed_key{hk} {}
+  field_map(QByteArray k, QByteArray v, QByteArray p, int hk, unsigned o) : key{std::move(k)},val{std::move(v)},printfc{
+          std::move(p)},hashed_key{hk},options{o} {}
+};
+
+/*
+ * a Class describing all the wonderful elements of xcsv files, in a
+ * nutshell.
+ * It completely shows that this began life as a C struct...baby steps.
+ */
+class XcsvFile {
+ public:
+  XcsvFile();
+
+  bool is_internal;            /* bool - is internal (1) or parsed (0) */
+
+  /* header lines for writing at the top of the file. */
+  QStringList prologue;
+
+  /* footer lines for writing at the bottom of the file. */
+  QStringList epilogue;
+
+  QString field_delimiter;     /* comma, quote, etc... */
+  QString field_encloser;              /* doublequote, etc... */
+  QString record_delimiter;    /* newline, c/r, etc... */
+
+  QString badchars;            /* characters we never write to output */
+
+  QList<field_map> ifields;    /* input field mapping */
+  QList<field_map> ofields;    /* output field mapping */
+
+  gpsbabel::File* file;
+  QTextStream* stream;
+  QTextCodec* codec;
+  QString fname;                 /* ptr to filename of above. */
+
+  QString description;         /* Description for help text */
+  QString extension;           /* preferred filename extension (for wrappers)*/
+
+  short_handle mkshort_handle;/* handle for mkshort() */
+  ff_type type;                /* format type for GUI wrappers. */
+
+  int gps_datum;               /* result of GPS_Lookup_Datum_Index */
+  gpsdata_type datatype;       /* can be wptdata, rtedata or trkdata */
+  /* ... or ZERO to keep the old behaviour */
+
+};
+
+
+/****************************************************************************/
+/* obligatory global struct                                                 */
+/****************************************************************************/
+extern XcsvFile xcsv_file;
+
+#endif  // XCSV_H_INCLUDED_